1/* Functions for image support on window system.
2   Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3                 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING.  If not, write to
19the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20Boston, MA 02110-1301, USA.  */
21
22#include <config.h>
23#include <stdio.h>
24#include <math.h>
25#include <ctype.h>
26
27#ifdef HAVE_UNISTD_H
28#include <unistd.h>
29#endif
30
31/* This makes the fields of a Display accessible, in Xlib header files.  */
32
33#define XLIB_ILLEGAL_ACCESS
34
35#include "lisp.h"
36#include "frame.h"
37#include "window.h"
38#include "dispextern.h"
39#include "blockinput.h"
40#include "systime.h"
41#include <epaths.h>
42#include "charset.h"
43#include "coding.h"
44
45
46#ifdef HAVE_X_WINDOWS
47#include "xterm.h"
48#include <sys/types.h>
49#include <sys/stat.h>
50
51#define COLOR_TABLE_SUPPORT 1
52
53typedef struct x_bitmap_record Bitmap_Record;
54#define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
55#define NO_PIXMAP None
56
57#define RGB_PIXEL_COLOR unsigned long
58
59#define PIX_MASK_RETAIN	0
60#define PIX_MASK_DRAW	1
61#endif /* HAVE_X_WINDOWS */
62
63
64#ifdef HAVE_NTGUI
65#include "w32term.h"
66
67/* W32_TODO : Color tables on W32.  */
68#undef COLOR_TABLE_SUPPORT
69
70typedef struct w32_bitmap_record Bitmap_Record;
71#define GET_PIXEL(ximg, x, y) GetPixel(ximg, x, y)
72#define NO_PIXMAP 0
73
74#define RGB_PIXEL_COLOR COLORREF
75
76#define PIX_MASK_RETAIN	0
77#define PIX_MASK_DRAW	1
78
79#define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual
80#define x_defined_color w32_defined_color
81#define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
82#endif /* HAVE_NTGUI */
83
84
85#ifdef MAC_OS
86#include "macterm.h"
87#include <sys/stat.h>
88#ifndef MAC_OSX
89#include <alloca.h>
90#include <sys/param.h>
91#endif
92#if TARGET_API_MAC_CARBON
93#ifdef MAC_OSX
94#include <QuickTime/QuickTime.h>
95#else  /* not MAC_OSX */
96#include <QuickTime.h>
97#endif	/* not MAC_OSX */
98#else  /* not TARGET_API_MAC_CARBON */
99#include <Windows.h>
100#include <Gestalt.h>
101#include <TextUtils.h>
102#include <ImageCompression.h>
103#include <QuickTimeComponents.h>
104#endif	/* not TARGET_API_MAC_CARBON */
105
106/* MAC_TODO : Color tables on Mac.  */
107#undef COLOR_TABLE_SUPPORT
108
109#define ZPixmap 0 		/* arbitrary */
110typedef struct mac_bitmap_record Bitmap_Record;
111
112#define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
113#define NO_PIXMAP 0
114
115#define RGB_PIXEL_COLOR unsigned long
116
117/* A black pixel in a mask bitmap/pixmap means ``draw a source
118   pixel''.  A white pixel means ``retain the current pixel''. */
119#define PIX_MASK_DRAW	RGB_TO_ULONG(0,0,0)
120#define PIX_MASK_RETAIN	RGB_TO_ULONG(255,255,255)
121
122#define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual
123#define x_defined_color mac_defined_color
124#define DefaultDepthOfScreen(screen) (one_mac_display_info.n_planes)
125
126#endif /* MAC_OS */
127
128
129/* Search path for bitmap files.  */
130
131Lisp_Object Vx_bitmap_file_path;
132
133
134static void x_disable_image P_ ((struct frame *, struct image *));
135static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object,
136				  Lisp_Object));
137
138static void init_color_table P_ ((void));
139static unsigned long lookup_rgb_color P_ ((struct frame *f, int r, int g, int b));
140#ifdef COLOR_TABLE_SUPPORT
141static void free_color_table P_ ((void));
142static unsigned long *colors_in_color_table P_ ((int *n));
143static unsigned long lookup_pixel_color P_ ((struct frame *f, unsigned long p));
144#endif
145
146/* Code to deal with bitmaps.  Bitmaps are referenced by their bitmap
147   id, which is just an int that this section returns.  Bitmaps are
148   reference counted so they can be shared among frames.
149
150   Bitmap indices are guaranteed to be > 0, so a negative number can
151   be used to indicate no bitmap.
152
153   If you use x_create_bitmap_from_data, then you must keep track of
154   the bitmaps yourself.  That is, creating a bitmap from the same
155   data more than once will not be caught.  */
156
157#ifdef MAC_OS
158
159static XImagePtr
160XGetImage (display, pixmap, x, y, width, height, plane_mask, format)
161     Display *display;		/* not used */
162     Pixmap pixmap;
163     int x, y;			/* not used */
164     unsigned int width, height; /* not used */
165     unsigned long plane_mask; 	/* not used */
166     int format;		/* not used */
167{
168#if GLYPH_DEBUG
169  xassert (x == 0 && y == 0);
170  {
171    Rect ri, rp;
172    SetRect (&ri, 0, 0, width, height);
173    xassert (EqualRect (&ri, GetPixBounds (GetGWorldPixMap (pixmap), &rp)));
174  }
175  xassert (! (pixelsLocked & GetPixelsState (GetGWorldPixMap (pixmap))));
176#endif
177
178  LockPixels (GetGWorldPixMap (pixmap));
179
180  return pixmap;
181}
182
183static void
184XPutPixel (ximage, x, y, pixel)
185     XImagePtr ximage;
186     int x, y;
187     unsigned long pixel;
188{
189  PixMapHandle pixmap = GetGWorldPixMap (ximage);
190  short depth = GetPixDepth (pixmap);
191
192#if defined (WORDS_BIG_ENDIAN) || !USE_CG_DRAWING
193  if (depth == 32)
194    {
195      char *base_addr = GetPixBaseAddr (pixmap);
196      short row_bytes = GetPixRowBytes (pixmap);
197
198      ((unsigned long *) (base_addr + y * row_bytes))[x] = 0xff000000 | pixel;
199    }
200  else
201#endif
202  if (depth == 1)
203    {
204      char *base_addr = GetPixBaseAddr (pixmap);
205      short row_bytes = GetPixRowBytes (pixmap);
206
207      if (pixel == PIX_MASK_DRAW)
208	base_addr[y * row_bytes + x / 8] |= (1 << 7) >> (x & 7);
209      else
210	base_addr[y * row_bytes + x / 8] &= ~((1 << 7) >> (x & 7));
211    }
212  else
213    {
214      CGrafPtr old_port;
215      GDHandle old_gdh;
216      RGBColor color;
217
218      GetGWorld (&old_port, &old_gdh);
219      SetGWorld (ximage, NULL);
220
221      color.red = RED16_FROM_ULONG (pixel);
222      color.green = GREEN16_FROM_ULONG (pixel);
223      color.blue = BLUE16_FROM_ULONG (pixel);
224
225      SetCPixel (x, y, &color);
226
227      SetGWorld (old_port, old_gdh);
228    }
229}
230
231static unsigned long
232XGetPixel (ximage, x, y)
233     XImagePtr ximage;
234     int x, y;
235{
236  PixMapHandle pixmap = GetGWorldPixMap (ximage);
237  short depth = GetPixDepth (pixmap);
238
239#if defined (WORDS_BIG_ENDIAN) || !USE_CG_DRAWING
240  if (depth == 32)
241    {
242      char *base_addr = GetPixBaseAddr (pixmap);
243      short row_bytes = GetPixRowBytes (pixmap);
244
245      return ((unsigned long *) (base_addr + y * row_bytes))[x] & 0x00ffffff;
246    }
247  else
248#endif
249  if (depth == 1)
250    {
251      char *base_addr = GetPixBaseAddr (pixmap);
252      short row_bytes = GetPixRowBytes (pixmap);
253
254      if (base_addr[y * row_bytes + x / 8] & (1 << (~x & 7)))
255	return PIX_MASK_DRAW;
256      else
257	return PIX_MASK_RETAIN;
258    }
259  else
260    {
261      CGrafPtr old_port;
262      GDHandle old_gdh;
263      RGBColor color;
264
265      GetGWorld (&old_port, &old_gdh);
266      SetGWorld (ximage, NULL);
267
268      GetCPixel (x, y, &color);
269
270      SetGWorld (old_port, old_gdh);
271      return RGB_TO_ULONG (color.red >> 8, color.green >> 8, color.blue >> 8);
272    }
273}
274
275static void
276XDestroyImage (ximg)
277     XImagePtr ximg;
278{
279  UnlockPixels (GetGWorldPixMap (ximg));
280}
281
282#if USE_CG_DRAWING
283static CGImageRef
284mac_create_cg_image_from_image (f, img)
285     struct frame *f;
286     struct image *img;
287{
288  Pixmap mask;
289  CGImageRef result = NULL;
290
291  BLOCK_INPUT;
292  if (img->mask)
293    mask = img->mask;
294  else
295    {
296      mask = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
297			    img->width, img->height, 1);
298      if (mask)
299	{
300	  CGrafPtr old_port;
301	  GDHandle old_gdh;
302	  Rect r;
303
304	  GetGWorld (&old_port, &old_gdh);
305	  SetGWorld (mask, NULL);
306	  BackColor (blackColor); /* Don't mask.  */
307	  SetRect (&r, 0, 0, img->width, img->height);
308	  EraseRect (&r);
309	  SetGWorld (old_port, old_gdh);
310	}
311    }
312  if (mask)
313    {
314      CreateCGImageFromPixMaps (GetGWorldPixMap (img->pixmap),
315				GetGWorldPixMap (mask), &result);
316      if (mask != img->mask)
317	XFreePixmap (FRAME_X_DISPLAY (f), mask);
318    }
319  UNBLOCK_INPUT;
320
321  return result;
322}
323#endif /* USE_CG_DRAWING */
324#endif /* MAC_OS */
325
326
327/* Functions to access the contents of a bitmap, given an id.  */
328
329int
330x_bitmap_height (f, id)
331     FRAME_PTR f;
332     int id;
333{
334  return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].height;
335}
336
337int
338x_bitmap_width (f, id)
339     FRAME_PTR f;
340     int id;
341{
342  return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].width;
343}
344
345#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
346int
347x_bitmap_pixmap (f, id)
348     FRAME_PTR f;
349     int id;
350{
351  return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
352}
353#endif
354
355#ifdef HAVE_X_WINDOWS
356int
357x_bitmap_mask (f, id)
358     FRAME_PTR f;
359     int id;
360{
361  return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].mask;
362}
363#endif
364
365/* Allocate a new bitmap record.  Returns index of new record.  */
366
367static int
368x_allocate_bitmap_record (f)
369     FRAME_PTR f;
370{
371  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
372  int i;
373
374  if (dpyinfo->bitmaps == NULL)
375    {
376      dpyinfo->bitmaps_size = 10;
377      dpyinfo->bitmaps
378	= (Bitmap_Record *) xmalloc (dpyinfo->bitmaps_size * sizeof (Bitmap_Record));
379      dpyinfo->bitmaps_last = 1;
380      return 1;
381    }
382
383  if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size)
384    return ++dpyinfo->bitmaps_last;
385
386  for (i = 0; i < dpyinfo->bitmaps_size; ++i)
387    if (dpyinfo->bitmaps[i].refcount == 0)
388      return i + 1;
389
390  dpyinfo->bitmaps_size *= 2;
391  dpyinfo->bitmaps
392    = (Bitmap_Record *) xrealloc (dpyinfo->bitmaps,
393				  dpyinfo->bitmaps_size * sizeof (Bitmap_Record));
394  return ++dpyinfo->bitmaps_last;
395}
396
397/* Add one reference to the reference count of the bitmap with id ID.  */
398
399void
400x_reference_bitmap (f, id)
401     FRAME_PTR f;
402     int id;
403{
404  ++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
405}
406
407/* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS.  */
408
409int
410x_create_bitmap_from_data (f, bits, width, height)
411     struct frame *f;
412     char *bits;
413     unsigned int width, height;
414{
415  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
416  int id;
417
418#ifdef HAVE_X_WINDOWS
419  Pixmap bitmap;
420  bitmap = XCreateBitmapFromData (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
421				  bits, width, height);
422  if (! bitmap)
423    return -1;
424#endif /* HAVE_X_WINDOWS */
425
426#ifdef HAVE_NTGUI
427  Pixmap bitmap;
428  bitmap = CreateBitmap (width, height,
429			 FRAME_X_DISPLAY_INFO (XFRAME (frame))->n_planes,
430			 FRAME_X_DISPLAY_INFO (XFRAME (frame))->n_cbits,
431			 bits);
432  if (! bitmap)
433    return -1;
434#endif /* HAVE_NTGUI */
435
436#ifdef MAC_OS
437  /* MAC_TODO: for now fail if width is not mod 16 (toolbox requires it) */
438  if (width % 16 != 0)
439    return -1;
440#endif
441
442  id = x_allocate_bitmap_record (f);
443#ifdef MAC_OS
444  dpyinfo->bitmaps[id - 1].bitmap_data = (char *) xmalloc (height * width);
445  bcopy (bits, dpyinfo->bitmaps[id - 1].bitmap_data, height * width);
446#endif  /* MAC_OS */
447
448  dpyinfo->bitmaps[id - 1].file = NULL;
449  dpyinfo->bitmaps[id - 1].height = height;
450  dpyinfo->bitmaps[id - 1].width = width;
451  dpyinfo->bitmaps[id - 1].refcount = 1;
452
453#ifdef HAVE_X_WINDOWS
454  dpyinfo->bitmaps[id - 1].pixmap = bitmap;
455  dpyinfo->bitmaps[id - 1].have_mask = 0;
456  dpyinfo->bitmaps[id - 1].depth = 1;
457#endif /* HAVE_X_WINDOWS */
458
459#ifdef HAVE_NTGUI
460  dpyinfo->bitmaps[id - 1].pixmap = bitmap;
461  dpyinfo->bitmaps[id - 1].hinst = NULL;
462  dpyinfo->bitmaps[id - 1].depth = 1;
463#endif /* HAVE_NTGUI */
464
465  return id;
466}
467
468/* Create bitmap from file FILE for frame F.  */
469
470int
471x_create_bitmap_from_file (f, file)
472     struct frame *f;
473     Lisp_Object file;
474{
475#ifdef MAC_OS
476  return -1;  /* MAC_TODO : bitmap support */
477#endif  /* MAC_OS */
478
479#ifdef HAVE_NTGUI
480  return -1;  /* W32_TODO : bitmap support */
481#endif /* HAVE_NTGUI */
482
483#ifdef HAVE_X_WINDOWS
484  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
485  unsigned int width, height;
486  Pixmap bitmap;
487  int xhot, yhot, result, id;
488  Lisp_Object found;
489  int fd;
490  char *filename;
491
492  /* Look for an existing bitmap with the same name.  */
493  for (id = 0; id < dpyinfo->bitmaps_last; ++id)
494    {
495      if (dpyinfo->bitmaps[id].refcount
496	  && dpyinfo->bitmaps[id].file
497	  && !strcmp (dpyinfo->bitmaps[id].file, (char *) SDATA (file)))
498	{
499	  ++dpyinfo->bitmaps[id].refcount;
500	  return id + 1;
501	}
502    }
503
504  /* Search bitmap-file-path for the file, if appropriate.  */
505  fd = openp (Vx_bitmap_file_path, file, Qnil, &found, Qnil);
506  if (fd < 0)
507    return -1;
508  emacs_close (fd);
509
510  filename = (char *) SDATA (found);
511
512  result = XReadBitmapFile (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
513			    filename, &width, &height, &bitmap, &xhot, &yhot);
514  if (result != BitmapSuccess)
515    return -1;
516
517  id = x_allocate_bitmap_record (f);
518  dpyinfo->bitmaps[id - 1].pixmap = bitmap;
519  dpyinfo->bitmaps[id - 1].have_mask = 0;
520  dpyinfo->bitmaps[id - 1].refcount = 1;
521  dpyinfo->bitmaps[id - 1].file = (char *) xmalloc (SBYTES (file) + 1);
522  dpyinfo->bitmaps[id - 1].depth = 1;
523  dpyinfo->bitmaps[id - 1].height = height;
524  dpyinfo->bitmaps[id - 1].width = width;
525  strcpy (dpyinfo->bitmaps[id - 1].file, SDATA (file));
526
527  return id;
528#endif /* HAVE_X_WINDOWS */
529}
530
531/* Free bitmap B.  */
532
533static void
534Free_Bitmap_Record (dpyinfo, bm)
535     Display_Info *dpyinfo;
536     Bitmap_Record *bm;
537{
538#ifdef HAVE_X_WINDOWS
539  XFreePixmap (dpyinfo->display, bm->pixmap);
540  if (bm->have_mask)
541    XFreePixmap (dpyinfo->display, bm->mask);
542#endif /* HAVE_X_WINDOWS */
543
544#ifdef HAVE_NTGUI
545  DeleteObject (bm->pixmap);
546#endif /* HAVE_NTGUI */
547
548#ifdef MAC_OS
549  xfree (bm->bitmap_data);  /* Added ++kfs */
550  bm->bitmap_data = NULL;
551#endif  /* MAC_OS */
552
553  if (bm->file)
554    {
555      xfree (bm->file);
556      bm->file = NULL;
557    }
558}
559
560/* Remove reference to bitmap with id number ID.  */
561
562void
563x_destroy_bitmap (f, id)
564     FRAME_PTR f;
565     int id;
566{
567  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
568
569  if (id > 0)
570    {
571      Bitmap_Record *bm = &dpyinfo->bitmaps[id - 1];
572
573      if (--bm->refcount == 0)
574	{
575	  BLOCK_INPUT;
576	  Free_Bitmap_Record (dpyinfo, bm);
577	  UNBLOCK_INPUT;
578	}
579    }
580}
581
582/* Free all the bitmaps for the display specified by DPYINFO.  */
583
584void
585x_destroy_all_bitmaps (dpyinfo)
586     Display_Info *dpyinfo;
587{
588  int i;
589  Bitmap_Record *bm = dpyinfo->bitmaps;
590
591  for (i = 0; i < dpyinfo->bitmaps_last; i++, bm++)
592    if (bm->refcount > 0)
593      Free_Bitmap_Record (dpyinfo, bm);
594
595  dpyinfo->bitmaps_last = 0;
596}
597
598
599#ifdef HAVE_X_WINDOWS
600
601/* Useful functions defined in the section
602   `Image type independent image structures' below. */
603
604static unsigned long four_corners_best P_ ((XImagePtr ximg,
605					    int *corners,
606					    unsigned long width,
607					    unsigned long height));
608
609static int x_create_x_image_and_pixmap P_ ((struct frame *f, int width, int height,
610					    int depth, XImagePtr *ximg,
611					    Pixmap *pixmap));
612
613static void x_destroy_x_image P_ ((XImagePtr ximg));
614
615
616/* Create a mask of a bitmap. Note is this not a perfect mask.
617   It's nicer with some borders in this context */
618
619int
620x_create_bitmap_mask (f, id)
621     struct frame *f;
622     int id;
623{
624  Pixmap pixmap, mask;
625  XImagePtr ximg, mask_img;
626  unsigned long width, height;
627  int result;
628  unsigned long bg;
629  unsigned long x, y, xp, xm, yp, ym;
630  GC gc;
631
632  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
633
634  if (!(id > 0))
635    return -1;
636
637  pixmap = x_bitmap_pixmap (f, id);
638  width = x_bitmap_width (f, id);
639  height = x_bitmap_height (f, id);
640
641  BLOCK_INPUT;
642  ximg = XGetImage (FRAME_X_DISPLAY (f), pixmap, 0, 0, width, height,
643		    ~0, ZPixmap);
644
645  if (!ximg)
646    {
647      UNBLOCK_INPUT;
648      return -1;
649    }
650
651  result = x_create_x_image_and_pixmap (f, width, height, 1, &mask_img, &mask);
652
653  UNBLOCK_INPUT;
654  if (!result)
655    {
656      XDestroyImage (ximg);
657      return -1;
658    }
659
660  bg = four_corners_best (ximg, NULL, width, height);
661
662  for (y = 0; y < ximg->height; ++y)
663    {
664      for (x = 0; x < ximg->width; ++x)
665	{
666	  xp = x != ximg->width - 1 ? x + 1 : 0;
667	  xm = x != 0 ? x - 1 : ximg->width - 1;
668	  yp = y != ximg->height - 1 ? y + 1 : 0;
669	  ym = y != 0 ? y - 1 : ximg->height - 1;
670	  if (XGetPixel (ximg, x, y) == bg
671	      && XGetPixel (ximg, x, yp) == bg
672	      && XGetPixel (ximg, x, ym) == bg
673	      && XGetPixel (ximg, xp, y) == bg
674	      && XGetPixel (ximg, xp, yp) == bg
675	      && XGetPixel (ximg, xp, ym) == bg
676	      && XGetPixel (ximg, xm, y) == bg
677	      && XGetPixel (ximg, xm, yp) == bg
678	      && XGetPixel (ximg, xm, ym) == bg)
679	    XPutPixel (mask_img, x, y, 0);
680	  else
681	    XPutPixel (mask_img, x, y, 1);
682	}
683    }
684
685  xassert (interrupt_input_blocked);
686  gc = XCreateGC (FRAME_X_DISPLAY (f), mask, 0, NULL);
687  XPutImage (FRAME_X_DISPLAY (f), mask, gc, mask_img, 0, 0, 0, 0,
688	     width, height);
689  XFreeGC (FRAME_X_DISPLAY (f), gc);
690
691  dpyinfo->bitmaps[id - 1].have_mask = 1;
692  dpyinfo->bitmaps[id - 1].mask = mask;
693
694  XDestroyImage (ximg);
695  x_destroy_x_image (mask_img);
696
697  return 0;
698}
699
700#endif /* HAVE_X_WINDOWS */
701
702
703/***********************************************************************
704			    Image types
705 ***********************************************************************/
706
707/* Value is the number of elements of vector VECTOR.  */
708
709#define DIM(VECTOR)	(sizeof (VECTOR) / sizeof *(VECTOR))
710
711/* List of supported image types.  Use define_image_type to add new
712   types.  Use lookup_image_type to find a type for a given symbol.  */
713
714static struct image_type *image_types;
715
716/* A list of symbols, one for each supported image type.  */
717
718Lisp_Object Vimage_types;
719
720/* An alist of image types and libraries that implement the type.  */
721
722Lisp_Object Vimage_library_alist;
723
724/* Cache for delayed-loading image types.  */
725
726static Lisp_Object Vimage_type_cache;
727
728/* The symbol `xbm' which is used as the type symbol for XBM images.  */
729
730Lisp_Object Qxbm;
731
732/* Keywords.  */
733
734extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile;
735extern Lisp_Object QCdata, QCtype, Qcount;
736extern Lisp_Object Qcenter;
737Lisp_Object QCascent, QCmargin, QCrelief;
738Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask;
739Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask;
740
741/* Other symbols.  */
742
743Lisp_Object Qlaplace, Qemboss, Qedge_detection, Qheuristic;
744
745/* Time in seconds after which images should be removed from the cache
746   if not displayed.  */
747
748Lisp_Object Vimage_cache_eviction_delay;
749
750/* Function prototypes.  */
751
752static Lisp_Object define_image_type P_ ((struct image_type *type, int loaded));
753static struct image_type *lookup_image_type P_ ((Lisp_Object symbol));
754static void image_error P_ ((char *format, Lisp_Object, Lisp_Object));
755static void x_laplace P_ ((struct frame *, struct image *));
756static void x_emboss P_ ((struct frame *, struct image *));
757static int x_build_heuristic_mask P_ ((struct frame *, struct image *,
758				       Lisp_Object));
759
760#define CACHE_IMAGE_TYPE(type, status) \
761  do { Vimage_type_cache = Fcons (Fcons (type, status), Vimage_type_cache); } while (0)
762
763#define ADD_IMAGE_TYPE(type) \
764  do { Vimage_types = Fcons (type, Vimage_types); } while (0)
765
766/* Define a new image type from TYPE.  This adds a copy of TYPE to
767   image_types and caches the loading status of TYPE.  */
768
769static Lisp_Object
770define_image_type (type, loaded)
771     struct image_type *type;
772     int loaded;
773{
774  Lisp_Object success;
775
776  if (!loaded)
777    success = Qnil;
778  else
779    {
780      /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
781         The initialized data segment is read-only.  */
782      struct image_type *p = (struct image_type *) xmalloc (sizeof *p);
783      bcopy (type, p, sizeof *p);
784      p->next = image_types;
785      image_types = p;
786      success = Qt;
787    }
788
789  CACHE_IMAGE_TYPE (*type->type, success);
790  return success;
791}
792
793
794/* Look up image type SYMBOL, and return a pointer to its image_type
795   structure.  Value is null if SYMBOL is not a known image type.  */
796
797static INLINE struct image_type *
798lookup_image_type (symbol)
799     Lisp_Object symbol;
800{
801  struct image_type *type;
802
803  /* We must initialize the image-type if it hasn't been already.  */
804  if (NILP (Finit_image_library (symbol, Vimage_library_alist)))
805    return 0;			/* unimplemented */
806
807  for (type = image_types; type; type = type->next)
808    if (EQ (symbol, *type->type))
809      break;
810
811  return type;
812}
813
814
815/* Value is non-zero if OBJECT is a valid Lisp image specification.  A
816   valid image specification is a list whose car is the symbol
817   `image', and whose rest is a property list.  The property list must
818   contain a value for key `:type'.  That value must be the name of a
819   supported image type.  The rest of the property list depends on the
820   image type.  */
821
822int
823valid_image_p (object)
824     Lisp_Object object;
825{
826  int valid_p = 0;
827
828  if (IMAGEP (object))
829    {
830      Lisp_Object tem;
831
832      for (tem = XCDR (object); CONSP (tem); tem = XCDR (tem))
833	if (EQ (XCAR (tem), QCtype))
834	  {
835	    tem = XCDR (tem);
836	    if (CONSP (tem) && SYMBOLP (XCAR (tem)))
837	      {
838		struct image_type *type;
839		type = lookup_image_type (XCAR (tem));
840		if (type)
841		  valid_p = type->valid_p (object);
842	      }
843
844	    break;
845	  }
846    }
847
848  return valid_p;
849}
850
851
852/* Log error message with format string FORMAT and argument ARG.
853   Signaling an error, e.g. when an image cannot be loaded, is not a
854   good idea because this would interrupt redisplay, and the error
855   message display would lead to another redisplay.  This function
856   therefore simply displays a message.  */
857
858static void
859image_error (format, arg1, arg2)
860     char *format;
861     Lisp_Object arg1, arg2;
862{
863  add_to_log (format, arg1, arg2);
864}
865
866
867
868/***********************************************************************
869			 Image specifications
870 ***********************************************************************/
871
872enum image_value_type
873{
874  IMAGE_DONT_CHECK_VALUE_TYPE,
875  IMAGE_STRING_VALUE,
876  IMAGE_STRING_OR_NIL_VALUE,
877  IMAGE_SYMBOL_VALUE,
878  IMAGE_POSITIVE_INTEGER_VALUE,
879  IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,
880  IMAGE_NON_NEGATIVE_INTEGER_VALUE,
881  IMAGE_ASCENT_VALUE,
882  IMAGE_INTEGER_VALUE,
883  IMAGE_FUNCTION_VALUE,
884  IMAGE_NUMBER_VALUE,
885  IMAGE_BOOL_VALUE
886};
887
888/* Structure used when parsing image specifications.  */
889
890struct image_keyword
891{
892  /* Name of keyword.  */
893  char *name;
894
895  /* The type of value allowed.  */
896  enum image_value_type type;
897
898  /* Non-zero means key must be present.  */
899  int mandatory_p;
900
901  /* Used to recognize duplicate keywords in a property list.  */
902  int count;
903
904  /* The value that was found.  */
905  Lisp_Object value;
906};
907
908
909static int parse_image_spec P_ ((Lisp_Object, struct image_keyword *,
910				 int, Lisp_Object));
911static Lisp_Object image_spec_value P_ ((Lisp_Object, Lisp_Object, int *));
912
913
914/* Parse image spec SPEC according to KEYWORDS.  A valid image spec
915   has the format (image KEYWORD VALUE ...).  One of the keyword/
916   value pairs must be `:type TYPE'.  KEYWORDS is a vector of
917   image_keywords structures of size NKEYWORDS describing other
918   allowed keyword/value pairs.  Value is non-zero if SPEC is valid.  */
919
920static int
921parse_image_spec (spec, keywords, nkeywords, type)
922     Lisp_Object spec;
923     struct image_keyword *keywords;
924     int nkeywords;
925     Lisp_Object type;
926{
927  int i;
928  Lisp_Object plist;
929
930  if (!IMAGEP (spec))
931    return 0;
932
933  plist = XCDR (spec);
934  while (CONSP (plist))
935    {
936      Lisp_Object key, value;
937
938      /* First element of a pair must be a symbol.  */
939      key = XCAR (plist);
940      plist = XCDR (plist);
941      if (!SYMBOLP (key))
942	return 0;
943
944      /* There must follow a value.  */
945      if (!CONSP (plist))
946	return 0;
947      value = XCAR (plist);
948      plist = XCDR (plist);
949
950      /* Find key in KEYWORDS.  Error if not found.  */
951      for (i = 0; i < nkeywords; ++i)
952	if (strcmp (keywords[i].name, SDATA (SYMBOL_NAME (key))) == 0)
953	  break;
954
955      if (i == nkeywords)
956	continue;
957
958      /* Record that we recognized the keyword.  If a keywords
959	 was found more than once, it's an error.  */
960      keywords[i].value = value;
961      ++keywords[i].count;
962
963      if (keywords[i].count > 1)
964	return 0;
965
966      /* Check type of value against allowed type.  */
967      switch (keywords[i].type)
968	{
969	case IMAGE_STRING_VALUE:
970	  if (!STRINGP (value))
971	    return 0;
972	  break;
973
974	case IMAGE_STRING_OR_NIL_VALUE:
975	  if (!STRINGP (value) && !NILP (value))
976	    return 0;
977	  break;
978
979	case IMAGE_SYMBOL_VALUE:
980	  if (!SYMBOLP (value))
981	    return 0;
982	  break;
983
984	case IMAGE_POSITIVE_INTEGER_VALUE:
985	  if (!INTEGERP (value) || XINT (value) <= 0)
986	    return 0;
987	  break;
988
989	case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR:
990	  if (INTEGERP (value) && XINT (value) >= 0)
991	    break;
992	  if (CONSP (value)
993	      && INTEGERP (XCAR (value)) && INTEGERP (XCDR (value))
994	      && XINT (XCAR (value)) >= 0 && XINT (XCDR (value)) >= 0)
995	    break;
996	  return 0;
997
998	case IMAGE_ASCENT_VALUE:
999	  if (SYMBOLP (value) && EQ (value, Qcenter))
1000	    break;
1001	  else if (INTEGERP (value)
1002		   && XINT (value) >= 0
1003		   && XINT (value) <= 100)
1004	    break;
1005	  return 0;
1006
1007	case IMAGE_NON_NEGATIVE_INTEGER_VALUE:
1008	  if (!INTEGERP (value) || XINT (value) < 0)
1009	    return 0;
1010	  break;
1011
1012	case IMAGE_DONT_CHECK_VALUE_TYPE:
1013	  break;
1014
1015	case IMAGE_FUNCTION_VALUE:
1016	  value = indirect_function (value);
1017	  if (SUBRP (value)
1018	      || COMPILEDP (value)
1019	      || (CONSP (value) && EQ (XCAR (value), Qlambda)))
1020	    break;
1021	  return 0;
1022
1023	case IMAGE_NUMBER_VALUE:
1024	  if (!INTEGERP (value) && !FLOATP (value))
1025	    return 0;
1026	  break;
1027
1028	case IMAGE_INTEGER_VALUE:
1029	  if (!INTEGERP (value))
1030	    return 0;
1031	  break;
1032
1033	case IMAGE_BOOL_VALUE:
1034	  if (!NILP (value) && !EQ (value, Qt))
1035	    return 0;
1036	  break;
1037
1038	default:
1039	  abort ();
1040	  break;
1041	}
1042
1043      if (EQ (key, QCtype) && !EQ (type, value))
1044	return 0;
1045    }
1046
1047  /* Check that all mandatory fields are present.  */
1048  for (i = 0; i < nkeywords; ++i)
1049    if (keywords[i].mandatory_p && keywords[i].count == 0)
1050      return 0;
1051
1052  return NILP (plist);
1053}
1054
1055
1056/* Return the value of KEY in image specification SPEC.  Value is nil
1057   if KEY is not present in SPEC.  if FOUND is not null, set *FOUND
1058   to 1 if KEY was found in SPEC, set it to 0 otherwise.  */
1059
1060static Lisp_Object
1061image_spec_value (spec, key, found)
1062     Lisp_Object spec, key;
1063     int *found;
1064{
1065  Lisp_Object tail;
1066
1067  xassert (valid_image_p (spec));
1068
1069  for (tail = XCDR (spec);
1070       CONSP (tail) && CONSP (XCDR (tail));
1071       tail = XCDR (XCDR (tail)))
1072    {
1073      if (EQ (XCAR (tail), key))
1074	{
1075	  if (found)
1076	    *found = 1;
1077	  return XCAR (XCDR (tail));
1078	}
1079    }
1080
1081  if (found)
1082    *found = 0;
1083  return Qnil;
1084}
1085
1086
1087DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0,
1088       doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
1089PIXELS non-nil means return the size in pixels, otherwise return the
1090size in canonical character units.
1091FRAME is the frame on which the image will be displayed.  FRAME nil
1092or omitted means use the selected frame.  */)
1093     (spec, pixels, frame)
1094     Lisp_Object spec, pixels, frame;
1095{
1096  Lisp_Object size;
1097
1098  size = Qnil;
1099  if (valid_image_p (spec))
1100    {
1101      struct frame *f = check_x_frame (frame);
1102      int id = lookup_image (f, spec);
1103      struct image *img = IMAGE_FROM_ID (f, id);
1104      int width = img->width + 2 * img->hmargin;
1105      int height = img->height + 2 * img->vmargin;
1106
1107      if (NILP (pixels))
1108	size = Fcons (make_float ((double) width / FRAME_COLUMN_WIDTH (f)),
1109		      make_float ((double) height / FRAME_LINE_HEIGHT (f)));
1110      else
1111	size = Fcons (make_number (width), make_number (height));
1112    }
1113  else
1114    error ("Invalid image specification");
1115
1116  return size;
1117}
1118
1119
1120DEFUN ("image-mask-p", Fimage_mask_p, Simage_mask_p, 1, 2, 0,
1121       doc: /* Return t if image SPEC has a mask bitmap.
1122FRAME is the frame on which the image will be displayed.  FRAME nil
1123or omitted means use the selected frame.  */)
1124     (spec, frame)
1125     Lisp_Object spec, frame;
1126{
1127  Lisp_Object mask;
1128
1129  mask = Qnil;
1130  if (valid_image_p (spec))
1131    {
1132      struct frame *f = check_x_frame (frame);
1133      int id = lookup_image (f, spec);
1134      struct image *img = IMAGE_FROM_ID (f, id);
1135      if (img->mask)
1136	mask = Qt;
1137    }
1138  else
1139    error ("Invalid image specification");
1140
1141  return mask;
1142}
1143
1144DEFUN ("image-extension-data", Fimage_extension_data, Simage_extension_data, 1, 2, 0,
1145       doc: /* Return extension data for image SPEC.
1146FRAME is the frame on which the image will be displayed.  FRAME nil
1147or omitted means use the selected frame.  */)
1148     (spec, frame)
1149     Lisp_Object spec, frame;
1150{
1151  Lisp_Object ext;
1152
1153  ext = Qnil;
1154  if (valid_image_p (spec))
1155    {
1156      struct frame *f = check_x_frame (frame);
1157      int id = lookup_image (f, spec);
1158      struct image *img = IMAGE_FROM_ID (f, id);
1159      ext = img->data.lisp_val;
1160    }
1161
1162  return ext;
1163}
1164
1165
1166/***********************************************************************
1167		 Image type independent image structures
1168 ***********************************************************************/
1169
1170static struct image *make_image P_ ((Lisp_Object spec, unsigned hash));
1171static void free_image P_ ((struct frame *f, struct image *img));
1172static int check_image_size P_ ((struct frame *f, int width, int height));
1173
1174#define MAX_IMAGE_SIZE 6.0
1175Lisp_Object Vmax_image_size;
1176
1177/* Allocate and return a new image structure for image specification
1178   SPEC.  SPEC has a hash value of HASH.  */
1179
1180static struct image *
1181make_image (spec, hash)
1182     Lisp_Object spec;
1183     unsigned hash;
1184{
1185  struct image *img = (struct image *) xmalloc (sizeof *img);
1186
1187  xassert (valid_image_p (spec));
1188  bzero (img, sizeof *img);
1189  img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL));
1190  xassert (img->type != NULL);
1191  img->spec = spec;
1192  img->data.lisp_val = Qnil;
1193  img->ascent = DEFAULT_IMAGE_ASCENT;
1194  img->hash = hash;
1195  img->corners[BOT_CORNER] = -1;  /* Full image */
1196  return img;
1197}
1198
1199
1200/* Free image IMG which was used on frame F, including its resources.  */
1201
1202static void
1203free_image (f, img)
1204     struct frame *f;
1205     struct image *img;
1206{
1207  if (img)
1208    {
1209      struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
1210
1211      /* Remove IMG from the hash table of its cache.  */
1212      if (img->prev)
1213	img->prev->next = img->next;
1214      else
1215	c->buckets[img->hash % IMAGE_CACHE_BUCKETS_SIZE] = img->next;
1216
1217      if (img->next)
1218	img->next->prev = img->prev;
1219
1220      c->images[img->id] = NULL;
1221
1222      /* Free resources, then free IMG.  */
1223      img->type->free (f, img);
1224      xfree (img);
1225    }
1226}
1227
1228/* Return 1 if the given widths and heights are valid for display;
1229   otherwise, return 0. */
1230
1231int
1232check_image_size (f, width, height)
1233     struct frame *f;
1234     int width;
1235     int height;
1236{
1237  int w, h;
1238
1239  if (width <= 0 || height <= 0)
1240    return 0;
1241
1242  if (INTEGERP (Vmax_image_size))
1243    w = h = XINT (Vmax_image_size);
1244  else if (FLOATP (Vmax_image_size))
1245    {
1246      if (f != NULL)
1247	{
1248	  w = FRAME_PIXEL_WIDTH (f);
1249	  h = FRAME_PIXEL_HEIGHT (f);
1250	}
1251      else
1252	w = h = 1024;  /* Arbitrary size for unknown frame. */
1253      w = (int) (XFLOAT_DATA (Vmax_image_size) * w);
1254      h = (int) (XFLOAT_DATA (Vmax_image_size) * h);
1255    }
1256  else
1257    return 1;
1258
1259  return (width <= w && height <= h);
1260}
1261
1262/* Prepare image IMG for display on frame F.  Must be called before
1263   drawing an image.  */
1264
1265void
1266prepare_image_for_display (f, img)
1267     struct frame *f;
1268     struct image *img;
1269{
1270  EMACS_TIME t;
1271
1272  /* We're about to display IMG, so set its timestamp to `now'.  */
1273  EMACS_GET_TIME (t);
1274  img->timestamp = EMACS_SECS (t);
1275
1276  /* If IMG doesn't have a pixmap yet, load it now, using the image
1277     type dependent loader function.  */
1278  if (img->pixmap == NO_PIXMAP && !img->load_failed_p)
1279    img->load_failed_p = img->type->load (f, img) == 0;
1280
1281#if defined (MAC_OS) && USE_CG_DRAWING
1282  if (!img->load_failed_p && img->data.ptr_val == NULL)
1283    {
1284      img->data.ptr_val = mac_create_cg_image_from_image (f, img);
1285      if (img->data.ptr_val == NULL)
1286	{
1287	  img->load_failed_p = 1;
1288	  img->type->free (f, img);
1289	}
1290    }
1291#endif
1292}
1293
1294
1295/* Value is the number of pixels for the ascent of image IMG when
1296   drawn in face FACE.  */
1297
1298int
1299image_ascent (img, face, slice)
1300     struct image *img;
1301     struct face *face;
1302     struct glyph_slice *slice;
1303{
1304  int height;
1305  int ascent;
1306
1307  if (slice->height == img->height)
1308    height = img->height + img->vmargin;
1309  else if (slice->y == 0)
1310    height = slice->height + img->vmargin;
1311  else
1312    height = slice->height;
1313
1314  if (img->ascent == CENTERED_IMAGE_ASCENT)
1315    {
1316      if (face->font)
1317	{
1318#ifdef HAVE_NTGUI
1319	  /* W32 specific version.  Why?. ++kfs  */
1320	  ascent = height / 2 - (FONT_DESCENT(face->font)
1321				 - FONT_BASE(face->font)) / 2;
1322#else
1323	  /* This expression is arranged so that if the image can't be
1324	     exactly centered, it will be moved slightly up.  This is
1325	     because a typical font is `top-heavy' (due to the presence
1326	     uppercase letters), so the image placement should err towards
1327	     being top-heavy too.  It also just generally looks better.  */
1328	  ascent = (height + face->font->ascent - face->font->descent + 1) / 2;
1329#endif /* HAVE_NTGUI */
1330	}
1331      else
1332	ascent = height / 2;
1333    }
1334  else
1335    ascent = (int) (height * img->ascent / 100.0);
1336
1337  return ascent;
1338}
1339
1340
1341/* Image background colors.  */
1342
1343/* Find the "best" corner color of a bitmap.
1344   On W32, XIMG is assumed to a device context with the bitmap selected.  */
1345
1346static RGB_PIXEL_COLOR
1347four_corners_best (ximg, corners, width, height)
1348     XImagePtr_or_DC ximg;
1349     int *corners;
1350     unsigned long width, height;
1351{
1352  RGB_PIXEL_COLOR corner_pixels[4], best;
1353  int i, best_count;
1354
1355  if (corners && corners[BOT_CORNER] >= 0)
1356    {
1357      /* Get the colors at the corner_pixels of ximg.  */
1358      corner_pixels[0] = GET_PIXEL (ximg, corners[LEFT_CORNER], corners[TOP_CORNER]);
1359      corner_pixels[1] = GET_PIXEL (ximg, corners[RIGHT_CORNER] - 1, corners[TOP_CORNER]);
1360      corner_pixels[2] = GET_PIXEL (ximg, corners[RIGHT_CORNER] - 1, corners[BOT_CORNER] - 1);
1361      corner_pixels[3] = GET_PIXEL (ximg, corners[LEFT_CORNER], corners[BOT_CORNER] - 1);
1362    }
1363  else
1364    {
1365      /* Get the colors at the corner_pixels of ximg.  */
1366      corner_pixels[0] = GET_PIXEL (ximg, 0, 0);
1367      corner_pixels[1] = GET_PIXEL (ximg, width - 1, 0);
1368      corner_pixels[2] = GET_PIXEL (ximg, width - 1, height - 1);
1369      corner_pixels[3] = GET_PIXEL (ximg, 0, height - 1);
1370    }
1371  /* Choose the most frequently found color as background.  */
1372  for (i = best_count = 0; i < 4; ++i)
1373    {
1374      int j, n;
1375
1376      for (j = n = 0; j < 4; ++j)
1377	if (corner_pixels[i] == corner_pixels[j])
1378	  ++n;
1379
1380      if (n > best_count)
1381	best = corner_pixels[i], best_count = n;
1382    }
1383
1384  return best;
1385}
1386
1387/* Portability macros */
1388
1389#ifdef HAVE_NTGUI
1390
1391#define Destroy_Image(img_dc, prev) \
1392  do { SelectObject (img_dc, prev); DeleteDC (img_dc); } while (0)
1393
1394#define Free_Pixmap(display, pixmap) \
1395  DeleteObject (pixmap)
1396
1397#else
1398
1399#define Destroy_Image(ximg, dummy) \
1400  XDestroyImage (ximg)
1401
1402#define Free_Pixmap(display, pixmap) \
1403  XFreePixmap (display, pixmap)
1404
1405#endif /* HAVE_NTGUI */
1406
1407
1408/* Return the `background' field of IMG.  If IMG doesn't have one yet,
1409   it is guessed heuristically.  If non-zero, XIMG is an existing
1410   XImage object (or device context with the image selected on W32) to
1411   use for the heuristic.  */
1412
1413RGB_PIXEL_COLOR
1414image_background (img, f, ximg)
1415     struct image *img;
1416     struct frame *f;
1417     XImagePtr_or_DC ximg;
1418{
1419  if (! img->background_valid)
1420    /* IMG doesn't have a background yet, try to guess a reasonable value.  */
1421    {
1422      int free_ximg = !ximg;
1423#ifdef HAVE_NTGUI
1424      HGDIOBJ prev;
1425#endif /* HAVE_NTGUI */
1426
1427      if (free_ximg)
1428	{
1429#ifndef HAVE_NTGUI
1430	  ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
1431			    0, 0, img->width, img->height, ~0, ZPixmap);
1432#else
1433	  HDC frame_dc = get_frame_dc (f);
1434	  ximg = CreateCompatibleDC (frame_dc);
1435	  release_frame_dc (f, frame_dc);
1436	  prev = SelectObject (ximg, img->pixmap);
1437#endif /* !HAVE_NTGUI */
1438	}
1439
1440      img->background = four_corners_best (ximg, img->corners, img->width, img->height);
1441
1442      if (free_ximg)
1443	Destroy_Image (ximg, prev);
1444
1445      img->background_valid = 1;
1446    }
1447
1448  return img->background;
1449}
1450
1451/* Return the `background_transparent' field of IMG.  If IMG doesn't
1452   have one yet, it is guessed heuristically.  If non-zero, MASK is an
1453   existing XImage object to use for the heuristic.  */
1454
1455int
1456image_background_transparent (img, f, mask)
1457     struct image *img;
1458     struct frame *f;
1459     XImagePtr_or_DC mask;
1460{
1461  if (! img->background_transparent_valid)
1462    /* IMG doesn't have a background yet, try to guess a reasonable value.  */
1463    {
1464      if (img->mask)
1465	{
1466	  int free_mask = !mask;
1467#ifdef HAVE_NTGUI
1468	  HGDIOBJ prev;
1469#endif /* HAVE_NTGUI */
1470
1471	  if (free_mask)
1472	    {
1473#ifndef HAVE_NTGUI
1474	      mask = XGetImage (FRAME_X_DISPLAY (f), img->mask,
1475				0, 0, img->width, img->height, ~0, ZPixmap);
1476#else
1477	      HDC frame_dc = get_frame_dc (f);
1478	      mask = CreateCompatibleDC (frame_dc);
1479	      release_frame_dc (f, frame_dc);
1480	      prev = SelectObject (mask, img->mask);
1481#endif /* HAVE_NTGUI */
1482	    }
1483
1484	  img->background_transparent
1485	    = (four_corners_best (mask, img->corners, img->width, img->height) == PIX_MASK_RETAIN);
1486
1487	  if (free_mask)
1488	    Destroy_Image (mask, prev);
1489	}
1490      else
1491	img->background_transparent = 0;
1492
1493      img->background_transparent_valid = 1;
1494    }
1495
1496  return img->background_transparent;
1497}
1498
1499
1500/***********************************************************************
1501		  Helper functions for X image types
1502 ***********************************************************************/
1503
1504static void x_clear_image_1 P_ ((struct frame *, struct image *, int,
1505				 int, int));
1506static void x_clear_image P_ ((struct frame *f, struct image *img));
1507static unsigned long x_alloc_image_color P_ ((struct frame *f,
1508					      struct image *img,
1509					      Lisp_Object color_name,
1510					      unsigned long dflt));
1511
1512
1513/* Clear X resources of image IMG on frame F.  PIXMAP_P non-zero means
1514   free the pixmap if any.  MASK_P non-zero means clear the mask
1515   pixmap if any.  COLORS_P non-zero means free colors allocated for
1516   the image, if any.  */
1517
1518static void
1519x_clear_image_1 (f, img, pixmap_p, mask_p, colors_p)
1520     struct frame *f;
1521     struct image *img;
1522     int pixmap_p, mask_p, colors_p;
1523{
1524  if (pixmap_p && img->pixmap)
1525    {
1526      Free_Pixmap (FRAME_X_DISPLAY (f), img->pixmap);
1527      img->pixmap = NO_PIXMAP;
1528      img->background_valid = 0;
1529    }
1530
1531  if (mask_p && img->mask)
1532    {
1533      Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
1534      img->mask = NO_PIXMAP;
1535      img->background_transparent_valid = 0;
1536    }
1537
1538  if (colors_p && img->ncolors)
1539    {
1540      /* MAC_TODO: color table support.  */
1541      /* W32_TODO: color table support.  */
1542#ifdef HAVE_X_WINDOWS
1543      x_free_colors (f, img->colors, img->ncolors);
1544#endif /* HAVE_X_WINDOWS */
1545      xfree (img->colors);
1546      img->colors = NULL;
1547      img->ncolors = 0;
1548    }
1549
1550#if defined (MAC_OS) && USE_CG_DRAWING
1551  if (img->data.ptr_val)
1552    {
1553      CGImageRelease (img->data.ptr_val);
1554      img->data.ptr_val = NULL;
1555    }
1556#endif
1557}
1558
1559/* Free X resources of image IMG which is used on frame F.  */
1560
1561static void
1562x_clear_image (f, img)
1563     struct frame *f;
1564     struct image *img;
1565{
1566  BLOCK_INPUT;
1567  x_clear_image_1 (f, img, 1, 1, 1);
1568  UNBLOCK_INPUT;
1569}
1570
1571
1572/* Allocate color COLOR_NAME for image IMG on frame F.  If color
1573   cannot be allocated, use DFLT.  Add a newly allocated color to
1574   IMG->colors, so that it can be freed again.  Value is the pixel
1575   color.  */
1576
1577static unsigned long
1578x_alloc_image_color (f, img, color_name, dflt)
1579     struct frame *f;
1580     struct image *img;
1581     Lisp_Object color_name;
1582     unsigned long dflt;
1583{
1584  XColor color;
1585  unsigned long result;
1586
1587  xassert (STRINGP (color_name));
1588
1589  if (x_defined_color (f, SDATA (color_name), &color, 1))
1590    {
1591      /* This isn't called frequently so we get away with simply
1592	 reallocating the color vector to the needed size, here.  */
1593      ++img->ncolors;
1594      img->colors =
1595	(unsigned long *) xrealloc (img->colors,
1596				    img->ncolors * sizeof *img->colors);
1597      img->colors[img->ncolors - 1] = color.pixel;
1598      result = color.pixel;
1599    }
1600  else
1601    result = dflt;
1602
1603  return result;
1604}
1605
1606
1607
1608/***********************************************************************
1609			     Image Cache
1610 ***********************************************************************/
1611
1612static void cache_image P_ ((struct frame *f, struct image *img));
1613static void postprocess_image P_ ((struct frame *, struct image *));
1614
1615/* Return a new, initialized image cache that is allocated from the
1616   heap.  Call free_image_cache to free an image cache.  */
1617
1618struct image_cache *
1619make_image_cache ()
1620{
1621  struct image_cache *c = (struct image_cache *) xmalloc (sizeof *c);
1622  int size;
1623
1624  bzero (c, sizeof *c);
1625  c->size = 50;
1626  c->images = (struct image **) xmalloc (c->size * sizeof *c->images);
1627  size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
1628  c->buckets = (struct image **) xmalloc (size);
1629  bzero (c->buckets, size);
1630  return c;
1631}
1632
1633
1634/* Free image cache of frame F.  Be aware that X frames share images
1635   caches.  */
1636
1637void
1638free_image_cache (f)
1639     struct frame *f;
1640{
1641  struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
1642  if (c)
1643    {
1644      int i;
1645
1646      /* Cache should not be referenced by any frame when freed.  */
1647      xassert (c->refcount == 0);
1648
1649      for (i = 0; i < c->used; ++i)
1650	free_image (f, c->images[i]);
1651      xfree (c->images);
1652      xfree (c->buckets);
1653      xfree (c);
1654      FRAME_X_IMAGE_CACHE (f) = NULL;
1655    }
1656}
1657
1658
1659/* Clear image cache of frame F.  FORCE_P non-zero means free all
1660   images.  FORCE_P zero means clear only images that haven't been
1661   displayed for some time.  Should be called from time to time to
1662   reduce the number of loaded images.  If image-eviction-seconds is
1663   non-nil, this frees images in the cache which weren't displayed for
1664   at least that many seconds.  */
1665
1666void
1667clear_image_cache (f, force_p)
1668     struct frame *f;
1669     int force_p;
1670{
1671  struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
1672
1673  if (c && INTEGERP (Vimage_cache_eviction_delay))
1674    {
1675      EMACS_TIME t;
1676      unsigned long old;
1677      int i, nfreed;
1678
1679      EMACS_GET_TIME (t);
1680      old = EMACS_SECS (t) - XFASTINT (Vimage_cache_eviction_delay);
1681
1682      /* Block input so that we won't be interrupted by a SIGIO
1683	 while being in an inconsistent state.  */
1684      BLOCK_INPUT;
1685
1686      for (i = nfreed = 0; i < c->used; ++i)
1687	{
1688	  struct image *img = c->images[i];
1689	  if (img != NULL
1690	      && (force_p || img->timestamp < old))
1691	    {
1692	      free_image (f, img);
1693	      ++nfreed;
1694	    }
1695	}
1696
1697      /* We may be clearing the image cache because, for example,
1698	 Emacs was iconified for a longer period of time.  In that
1699	 case, current matrices may still contain references to
1700	 images freed above.  So, clear these matrices.  */
1701      if (nfreed)
1702	{
1703	  Lisp_Object tail, frame;
1704
1705	  FOR_EACH_FRAME (tail, frame)
1706	    {
1707	      struct frame *f = XFRAME (frame);
1708	      if (FRAME_WINDOW_P (f)
1709		  && FRAME_X_IMAGE_CACHE (f) == c)
1710		clear_current_matrices (f);
1711	    }
1712
1713	  ++windows_or_buffers_changed;
1714	}
1715
1716      UNBLOCK_INPUT;
1717    }
1718}
1719
1720
1721DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache,
1722       0, 1, 0,
1723       doc: /* Clear the image cache of FRAME.
1724FRAME nil or omitted means use the selected frame.
1725FRAME t means clear the image caches of all frames.  */)
1726     (frame)
1727     Lisp_Object frame;
1728{
1729  if (EQ (frame, Qt))
1730    {
1731      Lisp_Object tail;
1732
1733      FOR_EACH_FRAME (tail, frame)
1734	if (FRAME_WINDOW_P (XFRAME (frame)))
1735	  clear_image_cache (XFRAME (frame), 1);
1736    }
1737  else
1738    clear_image_cache (check_x_frame (frame), 1);
1739
1740  return Qnil;
1741}
1742
1743
1744/* Compute masks and transform image IMG on frame F, as specified
1745   by the image's specification,  */
1746
1747static void
1748postprocess_image (f, img)
1749     struct frame *f;
1750     struct image *img;
1751{
1752  /* Manipulation of the image's mask.  */
1753  if (img->pixmap)
1754    {
1755      Lisp_Object conversion, spec;
1756      Lisp_Object mask;
1757
1758      spec = img->spec;
1759
1760      /* `:heuristic-mask t'
1761	 `:mask heuristic'
1762	 means build a mask heuristically.
1763	 `:heuristic-mask (R G B)'
1764	 `:mask (heuristic (R G B))'
1765	 means build a mask from color (R G B) in the
1766	 image.
1767	 `:mask nil'
1768	 means remove a mask, if any.  */
1769
1770      mask = image_spec_value (spec, QCheuristic_mask, NULL);
1771      if (!NILP (mask))
1772	x_build_heuristic_mask (f, img, mask);
1773      else
1774	{
1775	  int found_p;
1776
1777	  mask = image_spec_value (spec, QCmask, &found_p);
1778
1779	  if (EQ (mask, Qheuristic))
1780	    x_build_heuristic_mask (f, img, Qt);
1781	  else if (CONSP (mask)
1782		   && EQ (XCAR (mask), Qheuristic))
1783	    {
1784	      if (CONSP (XCDR (mask)))
1785		x_build_heuristic_mask (f, img, XCAR (XCDR (mask)));
1786	      else
1787		x_build_heuristic_mask (f, img, XCDR (mask));
1788	    }
1789	  else if (NILP (mask) && found_p && img->mask)
1790	    {
1791	      Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
1792	      img->mask = NO_PIXMAP;
1793	    }
1794	}
1795
1796
1797      /* Should we apply an image transformation algorithm?  */
1798      conversion = image_spec_value (spec, QCconversion, NULL);
1799      if (EQ (conversion, Qdisabled))
1800	x_disable_image (f, img);
1801      else if (EQ (conversion, Qlaplace))
1802	x_laplace (f, img);
1803      else if (EQ (conversion, Qemboss))
1804	x_emboss (f, img);
1805      else if (CONSP (conversion)
1806	       && EQ (XCAR (conversion), Qedge_detection))
1807	{
1808	  Lisp_Object tem;
1809	  tem = XCDR (conversion);
1810	  if (CONSP (tem))
1811	    x_edge_detection (f, img,
1812			      Fplist_get (tem, QCmatrix),
1813			      Fplist_get (tem, QCcolor_adjustment));
1814	}
1815    }
1816}
1817
1818
1819/* Return the id of image with Lisp specification SPEC on frame F.
1820   SPEC must be a valid Lisp image specification (see valid_image_p).  */
1821
1822int
1823lookup_image (f, spec)
1824     struct frame *f;
1825     Lisp_Object spec;
1826{
1827  struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
1828  struct image *img;
1829  int i;
1830  unsigned hash;
1831  struct gcpro gcpro1;
1832  EMACS_TIME now;
1833
1834  /* F must be a window-system frame, and SPEC must be a valid image
1835     specification.  */
1836  xassert (FRAME_WINDOW_P (f));
1837  xassert (valid_image_p (spec));
1838
1839  GCPRO1 (spec);
1840
1841  /* Look up SPEC in the hash table of the image cache.  */
1842  hash = sxhash (spec, 0);
1843  i = hash % IMAGE_CACHE_BUCKETS_SIZE;
1844
1845  for (img = c->buckets[i]; img; img = img->next)
1846    if (img->hash == hash && !NILP (Fequal (img->spec, spec)))
1847      break;
1848
1849  if (img && img->load_failed_p)
1850    {
1851      free_image (f, img);
1852      img = NULL;
1853    }
1854
1855  /* If not found, create a new image and cache it.  */
1856  if (img == NULL)
1857    {
1858      extern Lisp_Object Qpostscript;
1859
1860      BLOCK_INPUT;
1861      img = make_image (spec, hash);
1862      cache_image (f, img);
1863      img->load_failed_p = img->type->load (f, img) == 0;
1864
1865      /* If we can't load the image, and we don't have a width and
1866	 height, use some arbitrary width and height so that we can
1867	 draw a rectangle for it.  */
1868      if (img->load_failed_p)
1869	{
1870	  Lisp_Object value;
1871
1872	  value = image_spec_value (spec, QCwidth, NULL);
1873	  img->width = (INTEGERP (value)
1874			? XFASTINT (value) : DEFAULT_IMAGE_WIDTH);
1875	  value = image_spec_value (spec, QCheight, NULL);
1876	  img->height = (INTEGERP (value)
1877			 ? XFASTINT (value) : DEFAULT_IMAGE_HEIGHT);
1878	}
1879      else
1880	{
1881	  /* Handle image type independent image attributes
1882	     `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
1883	     `:background COLOR'.  */
1884	  Lisp_Object ascent, margin, relief, bg;
1885
1886	  ascent = image_spec_value (spec, QCascent, NULL);
1887	  if (INTEGERP (ascent))
1888	    img->ascent = XFASTINT (ascent);
1889	  else if (EQ (ascent, Qcenter))
1890	    img->ascent = CENTERED_IMAGE_ASCENT;
1891
1892	  margin = image_spec_value (spec, QCmargin, NULL);
1893	  if (INTEGERP (margin) && XINT (margin) >= 0)
1894	    img->vmargin = img->hmargin = XFASTINT (margin);
1895	  else if (CONSP (margin) && INTEGERP (XCAR (margin))
1896		   && INTEGERP (XCDR (margin)))
1897	    {
1898	      if (XINT (XCAR (margin)) > 0)
1899		img->hmargin = XFASTINT (XCAR (margin));
1900	      if (XINT (XCDR (margin)) > 0)
1901		img->vmargin = XFASTINT (XCDR (margin));
1902	    }
1903
1904	  relief = image_spec_value (spec, QCrelief, NULL);
1905	  if (INTEGERP (relief))
1906	    {
1907	      img->relief = XINT (relief);
1908	      img->hmargin += abs (img->relief);
1909	      img->vmargin += abs (img->relief);
1910	    }
1911
1912	  if (! img->background_valid)
1913	    {
1914	      bg = image_spec_value (img->spec, QCbackground, NULL);
1915	      if (!NILP (bg))
1916		{
1917		  img->background
1918		    = x_alloc_image_color (f, img, bg,
1919					   FRAME_BACKGROUND_PIXEL (f));
1920		  img->background_valid = 1;
1921		}
1922	    }
1923
1924	  /* Do image transformations and compute masks, unless we
1925	     don't have the image yet.  */
1926	  if (!EQ (*img->type->type, Qpostscript))
1927	    postprocess_image (f, img);
1928	}
1929
1930      UNBLOCK_INPUT;
1931    }
1932
1933  /* We're using IMG, so set its timestamp to `now'.  */
1934  EMACS_GET_TIME (now);
1935  img->timestamp = EMACS_SECS (now);
1936
1937  UNGCPRO;
1938
1939  /* Value is the image id.  */
1940  return img->id;
1941}
1942
1943
1944/* Cache image IMG in the image cache of frame F.  */
1945
1946static void
1947cache_image (f, img)
1948     struct frame *f;
1949     struct image *img;
1950{
1951  struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
1952  int i;
1953
1954  /* Find a free slot in c->images.  */
1955  for (i = 0; i < c->used; ++i)
1956    if (c->images[i] == NULL)
1957      break;
1958
1959  /* If no free slot found, maybe enlarge c->images.  */
1960  if (i == c->used && c->used == c->size)
1961    {
1962      c->size *= 2;
1963      c->images = (struct image **) xrealloc (c->images,
1964					      c->size * sizeof *c->images);
1965    }
1966
1967  /* Add IMG to c->images, and assign IMG an id.  */
1968  c->images[i] = img;
1969  img->id = i;
1970  if (i == c->used)
1971    ++c->used;
1972
1973  /* Add IMG to the cache's hash table.  */
1974  i = img->hash % IMAGE_CACHE_BUCKETS_SIZE;
1975  img->next = c->buckets[i];
1976  if (img->next)
1977    img->next->prev = img;
1978  img->prev = NULL;
1979  c->buckets[i] = img;
1980}
1981
1982
1983/* Call FN on every image in the image cache of frame F.  Used to mark
1984   Lisp Objects in the image cache.  */
1985
1986void
1987forall_images_in_image_cache (f, fn)
1988     struct frame *f;
1989     void (*fn) P_ ((struct image *img));
1990{
1991  if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f))
1992    {
1993      struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
1994      if (c)
1995	{
1996	  int i;
1997	  for (i = 0; i < c->used; ++i)
1998	    if (c->images[i])
1999	      fn (c->images[i]);
2000	}
2001    }
2002}
2003
2004
2005
2006/***********************************************************************
2007			  X / MAC / W32 support code
2008 ***********************************************************************/
2009
2010#ifdef HAVE_NTGUI
2011
2012/* Macro for defining functions that will be loaded from image DLLs.  */
2013#define DEF_IMGLIB_FN(func) int (FAR CDECL *fn_##func)()
2014
2015/* Macro for loading those image functions from the library.  */
2016#define LOAD_IMGLIB_FN(lib,func) {					\
2017    fn_##func = (void *) GetProcAddress (lib, #func);			\
2018    if (!fn_##func) return 0;						\
2019  }
2020
2021/* Load a DLL implementing an image type.
2022   The `image-library-alist' variable associates a symbol,
2023   identifying  an image type, to a list of possible filenames.
2024   The function returns NULL if no library could be loaded for
2025   the given image type, or if the library was previously loaded;
2026   else the handle of the DLL.  */
2027static HMODULE
2028w32_delayed_load (Lisp_Object libraries, Lisp_Object type)
2029{
2030  HMODULE library = NULL;
2031
2032  if (CONSP (libraries) && NILP (Fassq (type, Vimage_type_cache)))
2033    {
2034      Lisp_Object dlls = Fassq (type, libraries);
2035
2036      if (CONSP (dlls))
2037        for (dlls = XCDR (dlls); CONSP (dlls); dlls = XCDR (dlls))
2038          {
2039            CHECK_STRING_CAR (dlls);
2040            if (library = LoadLibrary (SDATA (XCAR (dlls))))
2041              break;
2042          }
2043    }
2044
2045  return library;
2046}
2047
2048#endif /* HAVE_NTGUI */
2049
2050static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int,
2051					    XImagePtr *, Pixmap *));
2052static void x_destroy_x_image P_ ((XImagePtr));
2053static void x_put_x_image P_ ((struct frame *, XImagePtr, Pixmap, int, int));
2054
2055
2056/* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
2057   frame F.  Set *XIMG and *PIXMAP to the XImage and Pixmap created.
2058   Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
2059   via xmalloc.  Print error messages via image_error if an error
2060   occurs.  Value is non-zero if successful.
2061
2062   On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
2063   should indicate the bit depth of the image.  */
2064
2065static int
2066x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap)
2067     struct frame *f;
2068     int width, height, depth;
2069     XImagePtr *ximg;
2070     Pixmap *pixmap;
2071{
2072#ifdef HAVE_X_WINDOWS
2073  Display *display = FRAME_X_DISPLAY (f);
2074  Window window = FRAME_X_WINDOW (f);
2075  Screen *screen = FRAME_X_SCREEN (f);
2076
2077  xassert (interrupt_input_blocked);
2078
2079  if (depth <= 0)
2080    depth = DefaultDepthOfScreen (screen);
2081  *ximg = XCreateImage (display, DefaultVisualOfScreen (screen),
2082			depth, ZPixmap, 0, NULL, width, height,
2083			depth > 16 ? 32 : depth > 8 ? 16 : 8, 0);
2084  if (*ximg == NULL)
2085    {
2086      image_error ("Unable to allocate X image", Qnil, Qnil);
2087      return 0;
2088    }
2089
2090  /* Allocate image raster.  */
2091  (*ximg)->data = (char *) xmalloc ((*ximg)->bytes_per_line * height);
2092
2093  /* Allocate a pixmap of the same size.  */
2094  *pixmap = XCreatePixmap (display, window, width, height, depth);
2095  if (*pixmap == NO_PIXMAP)
2096    {
2097      x_destroy_x_image (*ximg);
2098      *ximg = NULL;
2099      image_error ("Unable to create X pixmap", Qnil, Qnil);
2100      return 0;
2101    }
2102
2103  return 1;
2104#endif /* HAVE_X_WINDOWS */
2105
2106#ifdef HAVE_NTGUI
2107
2108  BITMAPINFOHEADER *header;
2109  HDC hdc;
2110  int scanline_width_bits;
2111  int remainder;
2112  int palette_colors = 0;
2113
2114  if (depth == 0)
2115    depth = 24;
2116
2117  if (depth != 1 && depth != 4 && depth != 8
2118      && depth != 16 && depth != 24 && depth != 32)
2119    {
2120      image_error ("Invalid image bit depth specified", Qnil, Qnil);
2121      return 0;
2122    }
2123
2124  scanline_width_bits = width * depth;
2125  remainder = scanline_width_bits % 32;
2126
2127  if (remainder)
2128    scanline_width_bits += 32 - remainder;
2129
2130  /* Bitmaps with a depth less than 16 need a palette.  */
2131  /* BITMAPINFO structure already contains the first RGBQUAD.  */
2132  if (depth < 16)
2133    palette_colors = 1 << depth - 1;
2134
2135  *ximg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD));
2136  if (*ximg == NULL)
2137    {
2138      image_error ("Unable to allocate memory for XImage", Qnil, Qnil);
2139      return 0;
2140    }
2141
2142  header = &((*ximg)->info.bmiHeader);
2143  bzero (&((*ximg)->info), sizeof (BITMAPINFO));
2144  header->biSize = sizeof (*header);
2145  header->biWidth = width;
2146  header->biHeight = -height;  /* negative indicates a top-down bitmap.  */
2147  header->biPlanes = 1;
2148  header->biBitCount = depth;
2149  header->biCompression = BI_RGB;
2150  header->biClrUsed = palette_colors;
2151
2152  /* TODO: fill in palette.  */
2153  if (depth == 1)
2154    {
2155      (*ximg)->info.bmiColors[0].rgbBlue = 0;
2156      (*ximg)->info.bmiColors[0].rgbGreen = 0;
2157      (*ximg)->info.bmiColors[0].rgbRed = 0;
2158      (*ximg)->info.bmiColors[0].rgbReserved = 0;
2159      (*ximg)->info.bmiColors[1].rgbBlue = 255;
2160      (*ximg)->info.bmiColors[1].rgbGreen = 255;
2161      (*ximg)->info.bmiColors[1].rgbRed = 255;
2162      (*ximg)->info.bmiColors[1].rgbReserved = 0;
2163    }
2164
2165  hdc = get_frame_dc (f);
2166
2167  /* Create a DIBSection and raster array for the bitmap,
2168     and store its handle in *pixmap.  */
2169  *pixmap = CreateDIBSection (hdc, &((*ximg)->info),
2170			      (depth < 16) ? DIB_PAL_COLORS : DIB_RGB_COLORS,
2171			      /* casting avoids a GCC warning */
2172			      (void **)&((*ximg)->data), NULL, 0);
2173
2174  /* Realize display palette and garbage all frames. */
2175  release_frame_dc (f, hdc);
2176
2177  if (*pixmap == NULL)
2178    {
2179      DWORD err = GetLastError();
2180      Lisp_Object errcode;
2181      /* All system errors are < 10000, so the following is safe.  */
2182      XSETINT (errcode, (int) err);
2183      image_error ("Unable to create bitmap, error code %d", errcode, Qnil);
2184      x_destroy_x_image (*ximg);
2185      return 0;
2186    }
2187
2188  return 1;
2189
2190#endif /* HAVE_NTGUI */
2191
2192#ifdef MAC_OS
2193  Display *display = FRAME_X_DISPLAY (f);
2194  Window window = FRAME_X_WINDOW (f);
2195
2196  xassert (interrupt_input_blocked);
2197
2198  /* Allocate a pixmap of the same size.  */
2199  *pixmap = XCreatePixmap (display, window, width, height, depth);
2200  if (*pixmap == NO_PIXMAP)
2201    {
2202      *ximg = NULL;
2203      image_error ("Unable to create X pixmap", Qnil, Qnil);
2204      return 0;
2205    }
2206
2207  LockPixels (GetGWorldPixMap (*pixmap));
2208  *ximg = *pixmap;
2209  return 1;
2210
2211#endif  /* MAC_OS */
2212}
2213
2214
2215/* Destroy XImage XIMG.  Free XIMG->data.  */
2216
2217static void
2218x_destroy_x_image (ximg)
2219     XImagePtr ximg;
2220{
2221  xassert (interrupt_input_blocked);
2222  if (ximg)
2223    {
2224#ifdef HAVE_X_WINDOWS
2225      xfree (ximg->data);
2226      ximg->data = NULL;
2227      XDestroyImage (ximg);
2228#endif /* HAVE_X_WINDOWS */
2229#ifdef HAVE_NTGUI
2230      /* Data will be freed by DestroyObject.  */
2231      ximg->data = NULL;
2232      xfree (ximg);
2233#endif /* HAVE_NTGUI */
2234#ifdef MAC_OS
2235      XDestroyImage (ximg);
2236#endif /* MAC_OS */
2237    }
2238}
2239
2240
2241/* Put XImage XIMG into pixmap PIXMAP on frame F.  WIDTH and HEIGHT
2242   are width and height of both the image and pixmap.  */
2243
2244static void
2245x_put_x_image (f, ximg, pixmap, width, height)
2246     struct frame *f;
2247     XImagePtr ximg;
2248     Pixmap pixmap;
2249     int width, height;
2250{
2251#ifdef HAVE_X_WINDOWS
2252  GC gc;
2253
2254  xassert (interrupt_input_blocked);
2255  gc = XCreateGC (FRAME_X_DISPLAY (f), pixmap, 0, NULL);
2256  XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, ximg, 0, 0, 0, 0, width, height);
2257  XFreeGC (FRAME_X_DISPLAY (f), gc);
2258#endif /* HAVE_X_WINDOWS */
2259
2260#ifdef HAVE_NTGUI
2261#if 0  /* I don't think this is necessary looking at where it is used.  */
2262  HDC hdc = get_frame_dc (f);
2263  SetDIBits (hdc, pixmap, 0, height, ximg->data, &(ximg->info), DIB_RGB_COLORS);
2264  release_frame_dc (f, hdc);
2265#endif
2266#endif /* HAVE_NTGUI */
2267
2268#ifdef MAC_OS
2269  xassert (ximg == pixmap);
2270#endif  /* MAC_OS */
2271}
2272
2273
2274/***********************************************************************
2275			      File Handling
2276 ***********************************************************************/
2277
2278static unsigned char *slurp_file P_ ((char *, int *));
2279
2280
2281/* Find image file FILE.  Look in data-directory, then
2282   x-bitmap-file-path.  Value is the encoded full name of the file
2283   found, or nil if not found.  */
2284
2285Lisp_Object
2286x_find_image_file (file)
2287     Lisp_Object file;
2288{
2289  Lisp_Object file_found, search_path;
2290  struct gcpro gcpro1, gcpro2;
2291  int fd;
2292
2293  file_found = Qnil;
2294  search_path = Fcons (Vdata_directory, Vx_bitmap_file_path);
2295  GCPRO2 (file_found, search_path);
2296
2297  /* Try to find FILE in data-directory, then x-bitmap-file-path.  */
2298  fd = openp (search_path, file, Qnil, &file_found, Qnil);
2299
2300  if (fd == -1)
2301    file_found = Qnil;
2302  else
2303    {
2304      file_found = ENCODE_FILE (file_found);
2305      close (fd);
2306    }
2307
2308  UNGCPRO;
2309  return file_found;
2310}
2311
2312
2313/* Read FILE into memory.  Value is a pointer to a buffer allocated
2314   with xmalloc holding FILE's contents.  Value is null if an error
2315   occurred.  *SIZE is set to the size of the file.  */
2316
2317static unsigned char *
2318slurp_file (file, size)
2319     char *file;
2320     int *size;
2321{
2322  FILE *fp = NULL;
2323  unsigned char *buf = NULL;
2324  struct stat st;
2325
2326  if (stat (file, &st) == 0
2327      && (fp = fopen (file, "rb")) != NULL
2328      && (buf = (unsigned char *) xmalloc (st.st_size),
2329	  fread (buf, 1, st.st_size, fp) == st.st_size))
2330    {
2331      *size = st.st_size;
2332      fclose (fp);
2333    }
2334  else
2335    {
2336      if (fp)
2337	fclose (fp);
2338      if (buf)
2339	{
2340	  xfree (buf);
2341	  buf = NULL;
2342	}
2343    }
2344
2345  return buf;
2346}
2347
2348
2349
2350#ifdef MAC_OS
2351
2352/***********************************************************************
2353			MAC Image Load Functions
2354 ***********************************************************************/
2355
2356static int image_load_quicktime P_ ((struct frame *, struct image *img,
2357				     OSType));
2358#ifdef MAC_OSX
2359static int image_load_quartz2d P_ ((struct frame *, struct image *img, int));
2360#endif
2361
2362static OSErr
2363find_image_fsspec (specified_file, file, fss)
2364     Lisp_Object specified_file, *file;
2365     FSSpec *fss;
2366{
2367  OSErr err;
2368  AEDesc desc;
2369
2370  *file = x_find_image_file (specified_file);
2371  if (!STRINGP (*file))
2372    return fnfErr;		/* file or directory not found;
2373				   incomplete pathname */
2374  /* Try to open the image file.  */
2375  err = AECoercePtr (TYPE_FILE_NAME, SDATA (*file),
2376		     SBYTES (*file), typeFSS, &desc);
2377  if (err == noErr)
2378    {
2379#if TARGET_API_MAC_CARBON
2380      err = AEGetDescData (&desc, fss, sizeof (FSSpec));
2381#else
2382      *fss = *(FSSpec *)(*(desc.dataHandle));
2383#endif
2384      AEDisposeDesc (&desc);
2385    }
2386  return err;
2387}
2388
2389static int
2390image_load_qt_1 (f, img, type, fss, dh)
2391     struct frame *f;
2392     struct image *img;
2393     OSType type;
2394     const FSSpec *fss;
2395     Handle dh;
2396{
2397  ComponentResult err;
2398  GraphicsImportComponent gi;
2399  Rect rect;
2400  int width, height;
2401  ImageDescriptionHandle desc_handle;
2402  short draw_all_pixels;
2403  Lisp_Object specified_bg;
2404  XColor color;
2405  XImagePtr ximg;
2406  RGBColor bg_color;
2407
2408  err = OpenADefaultComponent (GraphicsImporterComponentType, type, &gi);
2409  if (err != noErr)
2410    {
2411      image_error ("Cannot get importer component for `%s'", img->spec, Qnil);
2412      return 0;
2413    }
2414  if (dh == NULL)
2415    {
2416      /* read from file system spec */
2417      err = GraphicsImportSetDataFile (gi, fss);
2418      if (err != noErr)
2419	{
2420	  image_error ("Cannot set fsspec to graphics importer for '%s'",
2421		       img->spec, Qnil);
2422	  goto error;
2423	}
2424    }
2425  else
2426    {
2427      /* read from data handle */
2428      err = GraphicsImportSetDataHandle (gi, dh);
2429      if (err != noErr)
2430	{
2431	  image_error ("Cannot set data handle to graphics importer for `%s'",
2432		       img->spec, Qnil);
2433	  goto error;
2434	}
2435    }
2436  err = GraphicsImportGetImageDescription (gi, &desc_handle);
2437  if (err != noErr || desc_handle == NULL)
2438    {
2439      image_error ("Error reading `%s'", img->spec, Qnil);
2440      goto error;
2441    }
2442  width = img->width = (*desc_handle)->width;
2443  height = img->height = (*desc_handle)->height;
2444  DisposeHandle ((Handle)desc_handle);
2445
2446  if (!check_image_size (f, width, height))
2447    {
2448      image_error ("Invalid image size", Qnil, Qnil);
2449      goto error;
2450    }
2451
2452  err = GraphicsImportDoesDrawAllPixels (gi, &draw_all_pixels);
2453#if 0
2454  /* Don't check the error code here.  It may have an undocumented
2455     value -32766. */
2456  if (err != noErr)
2457    {
2458      image_error ("Error reading `%s'", img->spec, Qnil);
2459      goto error;
2460    }
2461#endif
2462  if (draw_all_pixels != graphicsImporterDrawsAllPixels)
2463    {
2464      specified_bg = image_spec_value (img->spec, QCbackground, NULL);
2465      if (!STRINGP (specified_bg) ||
2466	  !mac_defined_color (f, SDATA (specified_bg), &color, 0))
2467	{
2468	  color.pixel = FRAME_BACKGROUND_PIXEL (f);
2469	  color.red = RED16_FROM_ULONG (color.pixel);
2470	  color.green = GREEN16_FROM_ULONG (color.pixel);
2471	  color.blue = BLUE16_FROM_ULONG (color.pixel);
2472	}
2473    }
2474
2475  if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
2476    goto error;
2477  if (draw_all_pixels != graphicsImporterDrawsAllPixels)
2478    {
2479      CGrafPtr old_port;
2480      GDHandle old_gdh;
2481
2482      GetGWorld (&old_port, &old_gdh);
2483      SetGWorld (ximg, NULL);
2484      bg_color.red = color.red;
2485      bg_color.green = color.green;
2486      bg_color.blue = color.blue;
2487      RGBBackColor (&bg_color);
2488#if TARGET_API_MAC_CARBON
2489      GetPortBounds (ximg, &rect);
2490      EraseRect (&rect);
2491#else
2492      EraseRect (&(ximg->portRect));
2493#endif
2494      SetGWorld (old_port, old_gdh);
2495    }
2496  GraphicsImportSetGWorld (gi, ximg, NULL);
2497  GraphicsImportDraw (gi);
2498  CloseComponent (gi);
2499
2500  /* Maybe fill in the background field while we have ximg handy. */
2501  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
2502    IMAGE_BACKGROUND (img, f, ximg);
2503
2504  /* Put the image into the pixmap.  */
2505  x_put_x_image (f, ximg, img->pixmap, width, height);
2506  x_destroy_x_image (ximg);
2507  return 1;
2508
2509 error:
2510  CloseComponent (gi);
2511  return 0;
2512}
2513
2514
2515/* Load an image using the QuickTime Graphics Importer.
2516   Note: The alpha channel does not work for PNG images. */
2517static int
2518image_load_quicktime (f, img, type)
2519     struct frame *f;
2520     struct image *img;
2521     OSType type;
2522{
2523  Lisp_Object specified_file;
2524  Lisp_Object specified_data;
2525  OSErr err;
2526
2527  specified_file = image_spec_value (img->spec, QCfile, NULL);
2528  specified_data = image_spec_value (img->spec, QCdata, NULL);
2529
2530  if (NILP (specified_data))
2531    {
2532      /* Read from a file */
2533      Lisp_Object file;
2534      FSSpec fss;
2535
2536      err = find_image_fsspec (specified_file, &file, &fss);
2537      if (err != noErr)
2538	{
2539	  if (err == fnfErr)
2540	    image_error ("Cannot find image file `%s'", specified_file, Qnil);
2541	  else
2542	    image_error ("Cannot open `%s'", file, Qnil);
2543	  return 0;
2544	}
2545      return image_load_qt_1 (f, img, type, &fss, NULL);
2546    }
2547  else
2548    {
2549      /* Memory source! */
2550      int success_p;
2551      Handle dh;
2552
2553      err = PtrToHand (SDATA (specified_data), &dh, SBYTES (specified_data));
2554      if (err != noErr)
2555	{
2556	  image_error ("Cannot allocate data handle for `%s'",
2557		       img->spec, Qnil);
2558	  return 0;
2559	}
2560      success_p = image_load_qt_1 (f, img, type, NULL, dh);
2561      DisposeHandle (dh);
2562      return success_p;
2563    }
2564}
2565
2566
2567#ifdef MAC_OSX
2568/* Load a PNG/JPEG image using Quartz 2D decoding routines.
2569   CGImageCreateWithPNGDataProvider is provided after Mac OS X 10.2.
2570   So don't use this function directly but determine at runtime
2571   whether it exists. */
2572typedef CGImageRef (*CGImageCreateWithPNGDataProviderProcType)
2573  (CGDataProviderRef, const float [], bool, CGColorRenderingIntent);
2574static CGImageCreateWithPNGDataProviderProcType MyCGImageCreateWithPNGDataProvider;
2575
2576
2577static void
2578init_image_func_pointer ()
2579{
2580  if (NSIsSymbolNameDefined ("_CGImageCreateWithPNGDataProvider"))
2581    {
2582      MyCGImageCreateWithPNGDataProvider
2583	= (CGImageCreateWithPNGDataProviderProcType)
2584	NSAddressOfSymbol (NSLookupAndBindSymbol
2585			   ("_CGImageCreateWithPNGDataProvider"));
2586    }
2587  else
2588    MyCGImageCreateWithPNGDataProvider = NULL;
2589}
2590
2591
2592static int
2593image_load_quartz2d (f, img, png_p)
2594     struct frame *f;
2595     struct image *img;
2596     int png_p;
2597{
2598  Lisp_Object file, specified_file;
2599  Lisp_Object specified_data, specified_bg;
2600  struct gcpro gcpro1;
2601  CGDataProviderRef source;
2602  CGImageRef image;
2603  int width, height;
2604  XColor color;
2605  XImagePtr ximg = NULL;
2606  CGContextRef context;
2607  CGRect rectangle;
2608
2609  /* Open the file.  */
2610  specified_file = image_spec_value (img->spec, QCfile, NULL);
2611  specified_data = image_spec_value (img->spec, QCdata, NULL);
2612
2613  file = Qnil;
2614  GCPRO1 (file);
2615
2616  if (NILP (specified_data))
2617    {
2618      CFStringRef path;
2619      CFURLRef url;
2620
2621      file = x_find_image_file (specified_file);
2622      if (!STRINGP (file))
2623	{
2624	  image_error ("Cannot find image file `%s'", specified_file, Qnil);
2625	  UNGCPRO;
2626	  return 0;
2627	}
2628      path = cfstring_create_with_utf8_cstring (SDATA (file));
2629      url = CFURLCreateWithFileSystemPath (NULL, path,
2630					   kCFURLPOSIXPathStyle, 0);
2631      CFRelease (path);
2632      source = CGDataProviderCreateWithURL (url);
2633      CFRelease (url);
2634    }
2635  else
2636    source = CGDataProviderCreateWithData (NULL, SDATA (specified_data),
2637					   SBYTES (specified_data), NULL);
2638
2639  if (png_p)
2640    image = (*MyCGImageCreateWithPNGDataProvider) (source, NULL, FALSE,
2641						   kCGRenderingIntentDefault);
2642  else
2643    image = CGImageCreateWithJPEGDataProvider (source, NULL, FALSE,
2644					       kCGRenderingIntentDefault);
2645
2646  CGDataProviderRelease (source);
2647  if (image == NULL)
2648    {
2649      UNGCPRO;
2650      image_error ("Error reading image `%s'", img->spec, Qnil);
2651      return 0;
2652    }
2653  width = img->width = CGImageGetWidth (image);
2654  height = img->height = CGImageGetHeight (image);
2655
2656  if (!check_image_size (f, width, height))
2657    {
2658      CGImageRelease (image);
2659      UNGCPRO;
2660      image_error ("Invalid image size", Qnil, Qnil);
2661      return 0;
2662    }
2663
2664  if (png_p)
2665    {
2666      specified_bg = image_spec_value (img->spec, QCbackground, NULL);
2667      if (!STRINGP (specified_bg) ||
2668	  !mac_defined_color (f, SDATA (specified_bg), &color, 0))
2669	{
2670	  color.pixel = FRAME_BACKGROUND_PIXEL (f);
2671	  color.red = RED16_FROM_ULONG (color.pixel);
2672	  color.green = GREEN16_FROM_ULONG (color.pixel);
2673	  color.blue = BLUE16_FROM_ULONG (color.pixel);
2674	}
2675    }
2676
2677  if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
2678    {
2679      CGImageRelease (image);
2680      UNGCPRO;
2681      return 0;
2682    }
2683  rectangle = CGRectMake (0, 0, width, height);
2684  QDBeginCGContext (ximg, &context);
2685  if (png_p)
2686    {
2687      CGContextSetRGBFillColor (context, color.red / 65535.0,
2688				color.green / 65535.0,
2689				color.blue / 65535.0, 1.0);
2690      CGContextFillRect (context, rectangle);
2691    }
2692  CGContextDrawImage (context, rectangle, image);
2693  QDEndCGContext (ximg, &context);
2694  CGImageRelease (image);
2695
2696  /* Maybe fill in the background field while we have ximg handy. */
2697  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
2698    IMAGE_BACKGROUND (img, f, ximg);
2699
2700  /* Put the image into the pixmap.  */
2701  x_put_x_image (f, ximg, img->pixmap, width, height);
2702  x_destroy_x_image (ximg);
2703  UNGCPRO;
2704  return 1;
2705}
2706#endif
2707
2708#endif  /* MAC_OS */
2709
2710
2711/***********************************************************************
2712			      XBM images
2713 ***********************************************************************/
2714
2715static int xbm_scan P_ ((unsigned char **, unsigned char *, char *, int *));
2716static int xbm_load P_ ((struct frame *f, struct image *img));
2717static int xbm_load_image P_ ((struct frame *f, struct image *img,
2718			       unsigned char *, unsigned char *));
2719static int xbm_image_p P_ ((Lisp_Object object));
2720static int xbm_read_bitmap_data P_ ((struct frame *f,
2721				     unsigned char *, unsigned char *,
2722				     int *, int *, unsigned char **));
2723static int xbm_file_p P_ ((Lisp_Object));
2724
2725
2726/* Indices of image specification fields in xbm_format, below.  */
2727
2728enum xbm_keyword_index
2729{
2730  XBM_TYPE,
2731  XBM_FILE,
2732  XBM_WIDTH,
2733  XBM_HEIGHT,
2734  XBM_DATA,
2735  XBM_FOREGROUND,
2736  XBM_BACKGROUND,
2737  XBM_ASCENT,
2738  XBM_MARGIN,
2739  XBM_RELIEF,
2740  XBM_ALGORITHM,
2741  XBM_HEURISTIC_MASK,
2742  XBM_MASK,
2743  XBM_LAST
2744};
2745
2746/* Vector of image_keyword structures describing the format
2747   of valid XBM image specifications.  */
2748
2749static struct image_keyword xbm_format[XBM_LAST] =
2750{
2751  {":type",		IMAGE_SYMBOL_VALUE,			1},
2752  {":file",		IMAGE_STRING_VALUE,			0},
2753  {":width",		IMAGE_POSITIVE_INTEGER_VALUE,		0},
2754  {":height",		IMAGE_POSITIVE_INTEGER_VALUE,		0},
2755  {":data",		IMAGE_DONT_CHECK_VALUE_TYPE,		0},
2756  {":foreground",	IMAGE_STRING_OR_NIL_VALUE,		0},
2757  {":background",	IMAGE_STRING_OR_NIL_VALUE,		0},
2758  {":ascent",		IMAGE_ASCENT_VALUE,			0},
2759  {":margin",		IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,	0},
2760  {":relief",		IMAGE_INTEGER_VALUE,			0},
2761  {":conversion",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
2762  {":heuristic-mask",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
2763  {":mask",		IMAGE_DONT_CHECK_VALUE_TYPE,		0}
2764};
2765
2766/* Structure describing the image type XBM.  */
2767
2768static struct image_type xbm_type =
2769{
2770  &Qxbm,
2771  xbm_image_p,
2772  xbm_load,
2773  x_clear_image,
2774  NULL
2775};
2776
2777/* Tokens returned from xbm_scan.  */
2778
2779enum xbm_token
2780{
2781  XBM_TK_IDENT = 256,
2782  XBM_TK_NUMBER
2783};
2784
2785
2786/* Return non-zero if OBJECT is a valid XBM-type image specification.
2787   A valid specification is a list starting with the symbol `image'
2788   The rest of the list is a property list which must contain an
2789   entry `:type xbm..
2790
2791   If the specification specifies a file to load, it must contain
2792   an entry `:file FILENAME' where FILENAME is a string.
2793
2794   If the specification is for a bitmap loaded from memory it must
2795   contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
2796   WIDTH and HEIGHT are integers > 0.  DATA may be:
2797
2798   1. a string large enough to hold the bitmap data, i.e. it must
2799   have a size >= (WIDTH + 7) / 8 * HEIGHT
2800
2801   2. a bool-vector of size >= WIDTH * HEIGHT
2802
2803   3. a vector of strings or bool-vectors, one for each line of the
2804   bitmap.
2805
2806   4. A string containing an in-memory XBM file.  WIDTH and HEIGHT
2807   may not be specified in this case because they are defined in the
2808   XBM file.
2809
2810   Both the file and data forms may contain the additional entries
2811   `:background COLOR' and `:foreground COLOR'.  If not present,
2812   foreground and background of the frame on which the image is
2813   displayed is used.  */
2814
2815static int
2816xbm_image_p (object)
2817     Lisp_Object object;
2818{
2819  struct image_keyword kw[XBM_LAST];
2820
2821  bcopy (xbm_format, kw, sizeof kw);
2822  if (!parse_image_spec (object, kw, XBM_LAST, Qxbm))
2823    return 0;
2824
2825  xassert (EQ (kw[XBM_TYPE].value, Qxbm));
2826
2827  if (kw[XBM_FILE].count)
2828    {
2829      if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_DATA].count)
2830	return 0;
2831    }
2832  else if (kw[XBM_DATA].count && xbm_file_p (kw[XBM_DATA].value))
2833    {
2834      /* In-memory XBM file.  */
2835      if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_FILE].count)
2836	return 0;
2837    }
2838  else
2839    {
2840      Lisp_Object data;
2841      int width, height;
2842
2843      /* Entries for `:width', `:height' and `:data' must be present.  */
2844      if (!kw[XBM_WIDTH].count
2845	  || !kw[XBM_HEIGHT].count
2846	  || !kw[XBM_DATA].count)
2847	return 0;
2848
2849      data = kw[XBM_DATA].value;
2850      width = XFASTINT (kw[XBM_WIDTH].value);
2851      height = XFASTINT (kw[XBM_HEIGHT].value);
2852
2853      /* Check type of data, and width and height against contents of
2854	 data.  */
2855      if (VECTORP (data))
2856	{
2857	  int i;
2858
2859	  /* Number of elements of the vector must be >= height.  */
2860	  if (XVECTOR (data)->size < height)
2861	    return 0;
2862
2863	  /* Each string or bool-vector in data must be large enough
2864	     for one line of the image.  */
2865	  for (i = 0; i < height; ++i)
2866	    {
2867	      Lisp_Object elt = XVECTOR (data)->contents[i];
2868
2869	      if (STRINGP (elt))
2870		{
2871		  if (SCHARS (elt)
2872		      < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR)
2873		    return 0;
2874		}
2875	      else if (BOOL_VECTOR_P (elt))
2876		{
2877		  if (XBOOL_VECTOR (elt)->size < width)
2878		    return 0;
2879		}
2880	      else
2881		return 0;
2882	    }
2883	}
2884      else if (STRINGP (data))
2885	{
2886	  if (SCHARS (data)
2887	      < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR * height)
2888	    return 0;
2889	}
2890      else if (BOOL_VECTOR_P (data))
2891	{
2892	  if (XBOOL_VECTOR (data)->size < width * height)
2893	    return 0;
2894	}
2895      else
2896	return 0;
2897    }
2898
2899  return 1;
2900}
2901
2902
2903/* Scan a bitmap file.  FP is the stream to read from.  Value is
2904   either an enumerator from enum xbm_token, or a character for a
2905   single-character token, or 0 at end of file.  If scanning an
2906   identifier, store the lexeme of the identifier in SVAL.  If
2907   scanning a number, store its value in *IVAL.  */
2908
2909static int
2910xbm_scan (s, end, sval, ival)
2911     unsigned char **s, *end;
2912     char *sval;
2913     int *ival;
2914{
2915  unsigned int c;
2916
2917 loop:
2918
2919  /* Skip white space.  */
2920  while (*s < end && (c = *(*s)++, isspace (c)))
2921    ;
2922
2923  if (*s >= end)
2924    c = 0;
2925  else if (isdigit (c))
2926    {
2927      int value = 0, digit;
2928
2929      if (c == '0' && *s < end)
2930	{
2931	  c = *(*s)++;
2932	  if (c == 'x' || c == 'X')
2933	    {
2934	      while (*s < end)
2935		{
2936		  c = *(*s)++;
2937		  if (isdigit (c))
2938		    digit = c - '0';
2939		  else if (c >= 'a' && c <= 'f')
2940		    digit = c - 'a' + 10;
2941		  else if (c >= 'A' && c <= 'F')
2942		    digit = c - 'A' + 10;
2943		  else
2944		    break;
2945		  value = 16 * value + digit;
2946		}
2947	    }
2948	  else if (isdigit (c))
2949	    {
2950	      value = c - '0';
2951	      while (*s < end
2952		     && (c = *(*s)++, isdigit (c)))
2953		value = 8 * value + c - '0';
2954	    }
2955	}
2956      else
2957	{
2958	  value = c - '0';
2959	  while (*s < end
2960		 && (c = *(*s)++, isdigit (c)))
2961	    value = 10 * value + c - '0';
2962	}
2963
2964      if (*s < end)
2965	*s = *s - 1;
2966      *ival = value;
2967      c = XBM_TK_NUMBER;
2968    }
2969  else if (isalpha (c) || c == '_')
2970    {
2971      *sval++ = c;
2972      while (*s < end
2973	     && (c = *(*s)++, (isalnum (c) || c == '_')))
2974	*sval++ = c;
2975      *sval = 0;
2976      if (*s < end)
2977	*s = *s - 1;
2978      c = XBM_TK_IDENT;
2979    }
2980  else if (c == '/' && **s == '*')
2981    {
2982      /* C-style comment.  */
2983      ++*s;
2984      while (**s && (**s != '*' || *(*s + 1) != '/'))
2985	++*s;
2986      if (**s)
2987	{
2988	  *s += 2;
2989	  goto loop;
2990	}
2991    }
2992
2993  return c;
2994}
2995
2996#ifdef HAVE_NTGUI
2997
2998/* Create a Windows bitmap from X bitmap data.  */
2999static HBITMAP
3000w32_create_pixmap_from_bitmap_data (int width, int height, char *data)
3001{
3002  static unsigned char swap_nibble[16]
3003    = { 0x0, 0x8, 0x4, 0xc,    /* 0000 1000 0100 1100 */
3004	0x2, 0xa, 0x6, 0xe,    /* 0010 1010 0110 1110 */
3005	0x1, 0x9, 0x5, 0xd,    /* 0001 1001 0101 1101 */
3006	0x3, 0xb, 0x7, 0xf };  /* 0011 1011 0111 1111 */
3007  int i, j, w1, w2;
3008  unsigned char *bits, *p;
3009  HBITMAP bmp;
3010
3011  w1 = (width + 7) / 8;         /* nb of 8bits elt in X bitmap */
3012  w2 = ((width + 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
3013  bits = (unsigned char *) alloca (height * w2);
3014  bzero (bits, height * w2);
3015  for (i = 0; i < height; i++)
3016    {
3017      p = bits + i*w2;
3018      for (j = 0; j < w1; j++)
3019	{
3020	  /* Bitswap XBM bytes to match how Windows does things.  */
3021	  unsigned char c = *data++;
3022	  *p++ = (unsigned char)((swap_nibble[c & 0xf] << 4)
3023				 | (swap_nibble[(c>>4) & 0xf]));
3024	}
3025    }
3026  bmp = CreateBitmap (width, height, 1, 1, (char *) bits);
3027
3028  return bmp;
3029}
3030
3031static void convert_mono_to_color_image (f, img, foreground, background)
3032     struct frame *f;
3033     struct image *img;
3034     COLORREF foreground, background;
3035{
3036  HDC hdc, old_img_dc, new_img_dc;
3037  HGDIOBJ old_prev, new_prev;
3038  HBITMAP new_pixmap;
3039
3040  hdc = get_frame_dc (f);
3041  old_img_dc = CreateCompatibleDC (hdc);
3042  new_img_dc = CreateCompatibleDC (hdc);
3043  new_pixmap = CreateCompatibleBitmap (hdc, img->width, img->height);
3044  release_frame_dc (f, hdc);
3045  old_prev = SelectObject (old_img_dc, img->pixmap);
3046  new_prev = SelectObject (new_img_dc, new_pixmap);
3047  SetTextColor (new_img_dc, foreground);
3048  SetBkColor (new_img_dc, background);
3049
3050  BitBlt (new_img_dc, 0, 0, img->width, img->height, old_img_dc,
3051	  0, 0, SRCCOPY);
3052
3053  SelectObject (old_img_dc, old_prev);
3054  SelectObject (new_img_dc, new_prev);
3055  DeleteDC (old_img_dc);
3056  DeleteDC (new_img_dc);
3057  DeleteObject (img->pixmap);
3058  if (new_pixmap == 0)
3059    fprintf (stderr, "Failed to convert image to color.\n");
3060  else
3061    img->pixmap = new_pixmap;
3062}
3063
3064#define XBM_BIT_SHUFFLE(b) (~(b))
3065
3066#else
3067
3068#define XBM_BIT_SHUFFLE(b) (b)
3069
3070#endif /* HAVE_NTGUI */
3071
3072
3073static void
3074Create_Pixmap_From_Bitmap_Data(f, img, data, fg, bg, non_default_colors)
3075     struct frame *f;
3076     struct image *img;
3077     char *data;
3078     RGB_PIXEL_COLOR fg, bg;
3079     int non_default_colors;
3080{
3081#ifdef HAVE_NTGUI
3082  img->pixmap
3083    = w32_create_pixmap_from_bitmap_data (img->width, img->height, data);
3084
3085  /* If colors were specified, transfer the bitmap to a color one.  */
3086  if (non_default_colors)
3087    convert_mono_to_color_image (f, img, fg, bg);
3088#else
3089  img->pixmap
3090    = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
3091				   FRAME_X_WINDOW (f),
3092				   data,
3093				   img->width, img->height,
3094				   fg, bg,
3095				   DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
3096#endif /* HAVE_NTGUI */
3097}
3098
3099
3100
3101/* Replacement for XReadBitmapFileData which isn't available under old
3102   X versions.  CONTENTS is a pointer to a buffer to parse; END is the
3103   buffer's end.  Set *WIDTH and *HEIGHT to the width and height of
3104   the image.  Return in *DATA the bitmap data allocated with xmalloc.
3105   Value is non-zero if successful.  DATA null means just test if
3106   CONTENTS looks like an in-memory XBM file.  */
3107
3108static int
3109xbm_read_bitmap_data (f, contents, end, width, height, data)
3110     struct frame *f;
3111     unsigned char *contents, *end;
3112     int *width, *height;
3113     unsigned char **data;
3114{
3115  unsigned char *s = contents;
3116  char buffer[BUFSIZ];
3117  int padding_p = 0;
3118  int v10 = 0;
3119  int bytes_per_line, i, nbytes;
3120  unsigned char *p;
3121  int value;
3122  int LA1;
3123
3124#define match() \
3125     LA1 = xbm_scan (&s, end, buffer, &value)
3126
3127#define expect(TOKEN)		\
3128     if (LA1 != (TOKEN)) 	\
3129       goto failure;		\
3130     else			\
3131       match ()
3132
3133#define expect_ident(IDENT)					\
3134     if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0)	\
3135       match ();						\
3136     else							\
3137       goto failure
3138
3139  *width = *height = -1;
3140  if (data)
3141    *data = NULL;
3142  LA1 = xbm_scan (&s, end, buffer, &value);
3143
3144  /* Parse defines for width, height and hot-spots.  */
3145  while (LA1 == '#')
3146    {
3147      match ();
3148      expect_ident ("define");
3149      expect (XBM_TK_IDENT);
3150
3151      if (LA1 == XBM_TK_NUMBER)
3152	{
3153          char *p = strrchr (buffer, '_');
3154	  p = p ? p + 1 : buffer;
3155          if (strcmp (p, "width") == 0)
3156	    *width = value;
3157          else if (strcmp (p, "height") == 0)
3158	    *height = value;
3159	}
3160      expect (XBM_TK_NUMBER);
3161    }
3162
3163  if (!check_image_size (f, *width, *height))
3164    goto failure;
3165  else if (data == NULL)
3166    goto success;
3167
3168  /* Parse bits.  Must start with `static'.  */
3169  expect_ident ("static");
3170  if (LA1 == XBM_TK_IDENT)
3171    {
3172      if (strcmp (buffer, "unsigned") == 0)
3173	{
3174	  match ();
3175	  expect_ident ("char");
3176	}
3177      else if (strcmp (buffer, "short") == 0)
3178	{
3179	  match ();
3180	  v10 = 1;
3181	  if (*width % 16 && *width % 16 < 9)
3182	    padding_p = 1;
3183	}
3184      else if (strcmp (buffer, "char") == 0)
3185	match ();
3186      else
3187	goto failure;
3188    }
3189  else
3190    goto failure;
3191
3192  expect (XBM_TK_IDENT);
3193  expect ('[');
3194  expect (']');
3195  expect ('=');
3196  expect ('{');
3197
3198  bytes_per_line = (*width + 7) / 8 + padding_p;
3199  nbytes = bytes_per_line * *height;
3200  p = *data = (unsigned char *) xmalloc (nbytes);
3201
3202  if (v10)
3203    {
3204      for (i = 0; i < nbytes; i += 2)
3205	{
3206	  int val = value;
3207	  expect (XBM_TK_NUMBER);
3208
3209	  *p++ = XBM_BIT_SHUFFLE (val);
3210	  if (!padding_p || ((i + 2) % bytes_per_line))
3211	    *p++ = XBM_BIT_SHUFFLE (value >> 8);
3212
3213	  if (LA1 == ',' || LA1 == '}')
3214	    match ();
3215	  else
3216	    goto failure;
3217	}
3218    }
3219  else
3220    {
3221      for (i = 0; i < nbytes; ++i)
3222	{
3223	  int val = value;
3224	  expect (XBM_TK_NUMBER);
3225
3226	  *p++ = XBM_BIT_SHUFFLE (val);
3227
3228	  if (LA1 == ',' || LA1 == '}')
3229	    match ();
3230	  else
3231	    goto failure;
3232	}
3233    }
3234
3235 success:
3236  return 1;
3237
3238 failure:
3239
3240  if (data && *data)
3241    {
3242      xfree (*data);
3243      *data = NULL;
3244    }
3245  return 0;
3246
3247#undef match
3248#undef expect
3249#undef expect_ident
3250}
3251
3252
3253/* Load XBM image IMG which will be displayed on frame F from buffer
3254   CONTENTS.  END is the end of the buffer.  Value is non-zero if
3255   successful.  */
3256
3257static int
3258xbm_load_image (f, img, contents, end)
3259     struct frame *f;
3260     struct image *img;
3261     unsigned char *contents, *end;
3262{
3263  int rc;
3264  unsigned char *data;
3265  int success_p = 0;
3266
3267  rc = xbm_read_bitmap_data (f, contents, end, &img->width, &img->height, &data);
3268  if (rc)
3269    {
3270      unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
3271      unsigned long background = FRAME_BACKGROUND_PIXEL (f);
3272      int non_default_colors = 0;
3273      Lisp_Object value;
3274
3275      xassert (img->width > 0 && img->height > 0);
3276
3277      /* Get foreground and background colors, maybe allocate colors.  */
3278      value = image_spec_value (img->spec, QCforeground, NULL);
3279      if (!NILP (value))
3280	{
3281	  foreground = x_alloc_image_color (f, img, value, foreground);
3282	  non_default_colors = 1;
3283	}
3284      value = image_spec_value (img->spec, QCbackground, NULL);
3285      if (!NILP (value))
3286	{
3287	  background = x_alloc_image_color (f, img, value, background);
3288	  img->background = background;
3289	  img->background_valid = 1;
3290	  non_default_colors = 1;
3291	}
3292
3293      Create_Pixmap_From_Bitmap_Data (f, img, data,
3294				      foreground, background,
3295				      non_default_colors);
3296      xfree (data);
3297
3298      if (img->pixmap == NO_PIXMAP)
3299	{
3300	  x_clear_image (f, img);
3301	  image_error ("Unable to create X pixmap for `%s'", img->spec, Qnil);
3302	}
3303      else
3304	success_p = 1;
3305    }
3306  else
3307    image_error ("Error loading XBM image `%s'", img->spec, Qnil);
3308
3309  return success_p;
3310}
3311
3312
3313/* Value is non-zero if DATA looks like an in-memory XBM file.  */
3314
3315static int
3316xbm_file_p (data)
3317     Lisp_Object data;
3318{
3319  int w, h;
3320  return (STRINGP (data)
3321	  && xbm_read_bitmap_data (NULL, SDATA (data),
3322				   (SDATA (data)
3323				    + SBYTES (data)),
3324				   &w, &h, NULL));
3325}
3326
3327
3328/* Fill image IMG which is used on frame F with pixmap data.  Value is
3329   non-zero if successful.  */
3330
3331static int
3332xbm_load (f, img)
3333     struct frame *f;
3334     struct image *img;
3335{
3336  int success_p = 0;
3337  Lisp_Object file_name;
3338
3339  xassert (xbm_image_p (img->spec));
3340
3341  /* If IMG->spec specifies a file name, create a non-file spec from it.  */
3342  file_name = image_spec_value (img->spec, QCfile, NULL);
3343  if (STRINGP (file_name))
3344    {
3345      Lisp_Object file;
3346      unsigned char *contents;
3347      int size;
3348      struct gcpro gcpro1;
3349
3350      file = x_find_image_file (file_name);
3351      GCPRO1 (file);
3352      if (!STRINGP (file))
3353	{
3354	  image_error ("Cannot find image file `%s'", file_name, Qnil);
3355	  UNGCPRO;
3356	  return 0;
3357	}
3358
3359      contents = slurp_file (SDATA (file), &size);
3360      if (contents == NULL)
3361	{
3362	  image_error ("Error loading XBM image `%s'", img->spec, Qnil);
3363	  UNGCPRO;
3364	  return 0;
3365	}
3366
3367      success_p = xbm_load_image (f, img, contents, contents + size);
3368      UNGCPRO;
3369    }
3370  else
3371    {
3372      struct image_keyword fmt[XBM_LAST];
3373      Lisp_Object data;
3374      unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
3375      unsigned long background = FRAME_BACKGROUND_PIXEL (f);
3376      int non_default_colors = 0;
3377      char *bits;
3378      int parsed_p;
3379      int in_memory_file_p = 0;
3380
3381      /* See if data looks like an in-memory XBM file.  */
3382      data = image_spec_value (img->spec, QCdata, NULL);
3383      in_memory_file_p = xbm_file_p (data);
3384
3385      /* Parse the image specification.  */
3386      bcopy (xbm_format, fmt, sizeof fmt);
3387      parsed_p = parse_image_spec (img->spec, fmt, XBM_LAST, Qxbm);
3388      xassert (parsed_p);
3389
3390      /* Get specified width, and height.  */
3391      if (!in_memory_file_p)
3392	{
3393	  img->width = XFASTINT (fmt[XBM_WIDTH].value);
3394	  img->height = XFASTINT (fmt[XBM_HEIGHT].value);
3395	  xassert (img->width > 0 && img->height > 0);
3396	}
3397
3398      /* Get foreground and background colors, maybe allocate colors.  */
3399      if (fmt[XBM_FOREGROUND].count
3400	  && STRINGP (fmt[XBM_FOREGROUND].value))
3401	{
3402	  foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value,
3403					    foreground);
3404	  non_default_colors = 1;
3405	}
3406
3407      if (fmt[XBM_BACKGROUND].count
3408	  && STRINGP (fmt[XBM_BACKGROUND].value))
3409	{
3410	  background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value,
3411					    background);
3412	  non_default_colors = 1;
3413	}
3414
3415      if (in_memory_file_p)
3416	success_p = xbm_load_image (f, img, SDATA (data),
3417				    (SDATA (data)
3418				     + SBYTES (data)));
3419      else
3420	{
3421	  if (VECTORP (data))
3422	    {
3423	      int i;
3424	      char *p;
3425	      int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
3426
3427	      p = bits = (char *) alloca (nbytes * img->height);
3428	      for (i = 0; i < img->height; ++i, p += nbytes)
3429		{
3430		  Lisp_Object line = XVECTOR (data)->contents[i];
3431		  if (STRINGP (line))
3432		    bcopy (SDATA (line), p, nbytes);
3433		  else
3434		    bcopy (XBOOL_VECTOR (line)->data, p, nbytes);
3435		}
3436	    }
3437	  else if (STRINGP (data))
3438	    bits = SDATA (data);
3439	  else
3440	    bits = XBOOL_VECTOR (data)->data;
3441
3442	  /* Create the pixmap.  */
3443
3444	  Create_Pixmap_From_Bitmap_Data (f, img, bits,
3445					  foreground, background,
3446					  non_default_colors);
3447	  if (img->pixmap)
3448	    success_p = 1;
3449	  else
3450	    {
3451	      image_error ("Unable to create pixmap for XBM image `%s'",
3452			   img->spec, Qnil);
3453	      x_clear_image (f, img);
3454	    }
3455	}
3456    }
3457
3458  return success_p;
3459}
3460
3461
3462
3463/***********************************************************************
3464			      XPM images
3465 ***********************************************************************/
3466
3467#if defined (HAVE_XPM) || defined (MAC_OS)
3468
3469static int xpm_image_p P_ ((Lisp_Object object));
3470static int xpm_load P_ ((struct frame *f, struct image *img));
3471static int xpm_valid_color_symbols_p P_ ((Lisp_Object));
3472
3473#endif /* HAVE_XPM || MAC_OS */
3474
3475#ifdef HAVE_XPM
3476#ifdef HAVE_NTGUI
3477/* Indicate to xpm.h that we don't have Xlib.  */
3478#define FOR_MSW
3479/* simx.h in xpm defines XColor and XImage differently than Emacs.  */
3480/* It also defines Display the same way as Emacs, but gcc 3.3 still barfs.  */
3481#define XColor xpm_XColor
3482#define XImage xpm_XImage
3483#define Display xpm_Display
3484#define PIXEL_ALREADY_TYPEDEFED
3485#include "X11/xpm.h"
3486#undef FOR_MSW
3487#undef XColor
3488#undef XImage
3489#undef Display
3490#undef PIXEL_ALREADY_TYPEDEFED
3491#else
3492#include "X11/xpm.h"
3493#endif /* HAVE_NTGUI */
3494#endif /* HAVE_XPM */
3495
3496#if defined (HAVE_XPM) || defined (MAC_OS)
3497/* The symbol `xpm' identifying XPM-format images.  */
3498
3499Lisp_Object Qxpm;
3500
3501/* Indices of image specification fields in xpm_format, below.  */
3502
3503enum xpm_keyword_index
3504{
3505  XPM_TYPE,
3506  XPM_FILE,
3507  XPM_DATA,
3508  XPM_ASCENT,
3509  XPM_MARGIN,
3510  XPM_RELIEF,
3511  XPM_ALGORITHM,
3512  XPM_HEURISTIC_MASK,
3513  XPM_MASK,
3514  XPM_COLOR_SYMBOLS,
3515  XPM_BACKGROUND,
3516  XPM_LAST
3517};
3518
3519/* Vector of image_keyword structures describing the format
3520   of valid XPM image specifications.  */
3521
3522static struct image_keyword xpm_format[XPM_LAST] =
3523{
3524  {":type",		IMAGE_SYMBOL_VALUE,			1},
3525  {":file",		IMAGE_STRING_VALUE,			0},
3526  {":data",		IMAGE_STRING_VALUE,			0},
3527  {":ascent",		IMAGE_ASCENT_VALUE,			0},
3528  {":margin",		IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,	0},
3529  {":relief",		IMAGE_INTEGER_VALUE,			0},
3530  {":conversion",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
3531  {":heuristic-mask",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
3532  {":mask",		IMAGE_DONT_CHECK_VALUE_TYPE,		0},
3533  {":color-symbols",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
3534  {":background",	IMAGE_STRING_OR_NIL_VALUE,		0}
3535};
3536
3537/* Structure describing the image type XPM.  */
3538
3539static struct image_type xpm_type =
3540{
3541  &Qxpm,
3542  xpm_image_p,
3543  xpm_load,
3544  x_clear_image,
3545  NULL
3546};
3547
3548#ifdef HAVE_X_WINDOWS
3549
3550/* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
3551   functions for allocating image colors.  Our own functions handle
3552   color allocation failures more gracefully than the ones on the XPM
3553   lib.  */
3554
3555#if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
3556#define ALLOC_XPM_COLORS
3557#endif
3558#endif /* HAVE_X_WINDOWS */
3559
3560#ifdef ALLOC_XPM_COLORS
3561
3562static void xpm_init_color_cache P_ ((struct frame *, XpmAttributes *));
3563static void xpm_free_color_cache P_ ((void));
3564static int xpm_lookup_color P_ ((struct frame *, char *, XColor *));
3565static int xpm_color_bucket P_ ((char *));
3566static struct xpm_cached_color *xpm_cache_color P_ ((struct frame *, char *,
3567						     XColor *, int));
3568
3569/* An entry in a hash table used to cache color definitions of named
3570   colors.  This cache is necessary to speed up XPM image loading in
3571   case we do color allocations ourselves.  Without it, we would need
3572   a call to XParseColor per pixel in the image.  */
3573
3574struct xpm_cached_color
3575{
3576  /* Next in collision chain.  */
3577  struct xpm_cached_color *next;
3578
3579  /* Color definition (RGB and pixel color).  */
3580  XColor color;
3581
3582  /* Color name.  */
3583  char name[1];
3584};
3585
3586/* The hash table used for the color cache, and its bucket vector
3587   size.  */
3588
3589#define XPM_COLOR_CACHE_BUCKETS	1001
3590struct xpm_cached_color **xpm_color_cache;
3591
3592/* Initialize the color cache.  */
3593
3594static void
3595xpm_init_color_cache (f, attrs)
3596     struct frame *f;
3597     XpmAttributes *attrs;
3598{
3599  size_t nbytes = XPM_COLOR_CACHE_BUCKETS * sizeof *xpm_color_cache;
3600  xpm_color_cache = (struct xpm_cached_color **) xmalloc (nbytes);
3601  memset (xpm_color_cache, 0, nbytes);
3602  init_color_table ();
3603
3604  if (attrs->valuemask & XpmColorSymbols)
3605    {
3606      int i;
3607      XColor color;
3608
3609      for (i = 0; i < attrs->numsymbols; ++i)
3610	if (XParseColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
3611			 attrs->colorsymbols[i].value, &color))
3612	  {
3613	    color.pixel = lookup_rgb_color (f, color.red, color.green,
3614					    color.blue);
3615	    xpm_cache_color (f, attrs->colorsymbols[i].name, &color, -1);
3616	  }
3617    }
3618}
3619
3620/* Free the color cache.  */
3621
3622static void
3623xpm_free_color_cache ()
3624{
3625  struct xpm_cached_color *p, *next;
3626  int i;
3627
3628  for (i = 0; i < XPM_COLOR_CACHE_BUCKETS; ++i)
3629    for (p = xpm_color_cache[i]; p; p = next)
3630      {
3631	next = p->next;
3632	xfree (p);
3633      }
3634
3635  xfree (xpm_color_cache);
3636  xpm_color_cache = NULL;
3637  free_color_table ();
3638}
3639
3640/* Return the bucket index for color named COLOR_NAME in the color
3641   cache.  */
3642
3643static int
3644xpm_color_bucket (color_name)
3645     char *color_name;
3646{
3647  unsigned h = 0;
3648  char *s;
3649
3650  for (s = color_name; *s; ++s)
3651    h = (h << 2) ^ *s;
3652  return h %= XPM_COLOR_CACHE_BUCKETS;
3653}
3654
3655
3656/* On frame F, cache values COLOR for color with name COLOR_NAME.
3657   BUCKET, if >= 0, is a precomputed bucket index.  Value is the cache
3658   entry added.  */
3659
3660static struct xpm_cached_color *
3661xpm_cache_color (f, color_name, color, bucket)
3662     struct frame *f;
3663     char *color_name;
3664     XColor *color;
3665     int bucket;
3666{
3667  size_t nbytes;
3668  struct xpm_cached_color *p;
3669
3670  if (bucket < 0)
3671    bucket = xpm_color_bucket (color_name);
3672
3673  nbytes = sizeof *p + strlen (color_name);
3674  p = (struct xpm_cached_color *) xmalloc (nbytes);
3675  strcpy (p->name, color_name);
3676  p->color = *color;
3677  p->next = xpm_color_cache[bucket];
3678  xpm_color_cache[bucket] = p;
3679  return p;
3680}
3681
3682/* Look up color COLOR_NAME for frame F in the color cache.  If found,
3683   return the cached definition in *COLOR.  Otherwise, make a new
3684   entry in the cache and allocate the color.  Value is zero if color
3685   allocation failed.  */
3686
3687static int
3688xpm_lookup_color (f, color_name, color)
3689     struct frame *f;
3690     char *color_name;
3691     XColor *color;
3692{
3693  struct xpm_cached_color *p;
3694  int h = xpm_color_bucket (color_name);
3695
3696  for (p = xpm_color_cache[h]; p; p = p->next)
3697    if (strcmp (p->name, color_name) == 0)
3698      break;
3699
3700  if (p != NULL)
3701    *color = p->color;
3702  else if (XParseColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
3703			color_name, color))
3704    {
3705      color->pixel = lookup_rgb_color (f, color->red, color->green,
3706				       color->blue);
3707      p = xpm_cache_color (f, color_name, color, h);
3708    }
3709  /* You get `opaque' at least from ImageMagick converting pbm to xpm
3710     with transparency, and it's useful.  */
3711  else if (strcmp ("opaque", color_name) == 0)
3712    {
3713      bzero (color, sizeof (XColor));  /* Is this necessary/correct?  */
3714      color->pixel = FRAME_FOREGROUND_PIXEL (f);
3715      p = xpm_cache_color (f, color_name, color, h);
3716    }
3717
3718  return p != NULL;
3719}
3720
3721
3722/* Callback for allocating color COLOR_NAME.  Called from the XPM lib.
3723   CLOSURE is a pointer to the frame on which we allocate the
3724   color.  Return in *COLOR the allocated color.  Value is non-zero
3725   if successful.  */
3726
3727static int
3728xpm_alloc_color (dpy, cmap, color_name, color, closure)
3729     Display *dpy;
3730     Colormap cmap;
3731     char *color_name;
3732     XColor *color;
3733     void *closure;
3734{
3735  return xpm_lookup_color ((struct frame *) closure, color_name, color);
3736}
3737
3738
3739/* Callback for freeing NPIXELS colors contained in PIXELS.  CLOSURE
3740   is a pointer to the frame on which we allocate the color.  Value is
3741   non-zero if successful.  */
3742
3743static int
3744xpm_free_colors (dpy, cmap, pixels, npixels, closure)
3745     Display *dpy;
3746     Colormap cmap;
3747     Pixel *pixels;
3748     int npixels;
3749     void *closure;
3750{
3751  return 1;
3752}
3753
3754#endif /* ALLOC_XPM_COLORS */
3755
3756
3757#ifdef HAVE_NTGUI
3758
3759/* XPM library details.  */
3760
3761DEF_IMGLIB_FN (XpmFreeAttributes);
3762DEF_IMGLIB_FN (XpmCreateImageFromBuffer);
3763DEF_IMGLIB_FN (XpmReadFileToImage);
3764DEF_IMGLIB_FN (XImageFree);
3765
3766static int
3767init_xpm_functions (Lisp_Object libraries)
3768{
3769  HMODULE library;
3770
3771  if (!(library = w32_delayed_load (libraries, Qxpm)))
3772    return 0;
3773
3774  LOAD_IMGLIB_FN (library, XpmFreeAttributes);
3775  LOAD_IMGLIB_FN (library, XpmCreateImageFromBuffer);
3776  LOAD_IMGLIB_FN (library, XpmReadFileToImage);
3777  LOAD_IMGLIB_FN (library, XImageFree);
3778  return 1;
3779}
3780
3781#endif /* HAVE_NTGUI */
3782
3783
3784/* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
3785   for XPM images.  Such a list must consist of conses whose car and
3786   cdr are strings.  */
3787
3788static int
3789xpm_valid_color_symbols_p (color_symbols)
3790     Lisp_Object color_symbols;
3791{
3792  while (CONSP (color_symbols))
3793    {
3794      Lisp_Object sym = XCAR (color_symbols);
3795      if (!CONSP (sym)
3796	  || !STRINGP (XCAR (sym))
3797	  || !STRINGP (XCDR (sym)))
3798	break;
3799      color_symbols = XCDR (color_symbols);
3800    }
3801
3802  return NILP (color_symbols);
3803}
3804
3805
3806/* Value is non-zero if OBJECT is a valid XPM image specification.  */
3807
3808static int
3809xpm_image_p (object)
3810     Lisp_Object object;
3811{
3812  struct image_keyword fmt[XPM_LAST];
3813  bcopy (xpm_format, fmt, sizeof fmt);
3814  return (parse_image_spec (object, fmt, XPM_LAST, Qxpm)
3815	  /* Either `:file' or `:data' must be present.  */
3816	  && fmt[XPM_FILE].count + fmt[XPM_DATA].count == 1
3817	  /* Either no `:color-symbols' or it's a list of conses
3818	     whose car and cdr are strings.  */
3819	  && (fmt[XPM_COLOR_SYMBOLS].count == 0
3820	      || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
3821}
3822
3823#endif /* HAVE_XPM || MAC_OS */
3824
3825#if defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
3826int
3827x_create_bitmap_from_xpm_data (f, bits)
3828     struct frame *f;
3829     char **bits;
3830{
3831  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3832  int id, rc;
3833  XpmAttributes attrs;
3834  Pixmap bitmap, mask;
3835
3836  bzero (&attrs, sizeof attrs);
3837
3838  attrs.visual = FRAME_X_VISUAL (f);
3839  attrs.colormap = FRAME_X_COLORMAP (f);
3840  attrs.valuemask |= XpmVisual;
3841  attrs.valuemask |= XpmColormap;
3842
3843  rc = XpmCreatePixmapFromData (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3844				bits, &bitmap, &mask, &attrs);
3845  if (rc != XpmSuccess)
3846    {
3847      XpmFreeAttributes (&attrs);
3848      return -1;
3849    }
3850
3851  id = x_allocate_bitmap_record (f);
3852  dpyinfo->bitmaps[id - 1].pixmap = bitmap;
3853  dpyinfo->bitmaps[id - 1].have_mask = 1;
3854  dpyinfo->bitmaps[id - 1].mask = mask;
3855  dpyinfo->bitmaps[id - 1].file = NULL;
3856  dpyinfo->bitmaps[id - 1].height = attrs.height;
3857  dpyinfo->bitmaps[id - 1].width = attrs.width;
3858  dpyinfo->bitmaps[id - 1].depth = attrs.depth;
3859  dpyinfo->bitmaps[id - 1].refcount = 1;
3860
3861  XpmFreeAttributes (&attrs);
3862  return id;
3863}
3864#endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */
3865
3866/* Load image IMG which will be displayed on frame F.  Value is
3867   non-zero if successful.  */
3868
3869#ifdef HAVE_XPM
3870
3871static int
3872xpm_load (f, img)
3873     struct frame *f;
3874     struct image *img;
3875{
3876  int rc;
3877  XpmAttributes attrs;
3878  Lisp_Object specified_file, color_symbols;
3879#ifdef HAVE_NTGUI
3880  HDC hdc;
3881  xpm_XImage * xpm_image = NULL, * xpm_mask = NULL;
3882#endif /* HAVE_NTGUI */
3883
3884  /* Configure the XPM lib.  Use the visual of frame F.  Allocate
3885     close colors.  Return colors allocated.  */
3886  bzero (&attrs, sizeof attrs);
3887
3888#ifndef HAVE_NTGUI
3889  attrs.visual = FRAME_X_VISUAL (f);
3890  attrs.colormap = FRAME_X_COLORMAP (f);
3891  attrs.valuemask |= XpmVisual;
3892  attrs.valuemask |= XpmColormap;
3893#endif /* HAVE_NTGUI */
3894
3895#ifdef ALLOC_XPM_COLORS
3896  /* Allocate colors with our own functions which handle
3897     failing color allocation more gracefully.  */
3898  attrs.color_closure = f;
3899  attrs.alloc_color = xpm_alloc_color;
3900  attrs.free_colors = xpm_free_colors;
3901  attrs.valuemask |= XpmAllocColor | XpmFreeColors | XpmColorClosure;
3902#else /* not ALLOC_XPM_COLORS */
3903  /* Let the XPM lib allocate colors.  */
3904  attrs.valuemask |= XpmReturnAllocPixels;
3905#ifdef XpmAllocCloseColors
3906  attrs.alloc_close_colors = 1;
3907  attrs.valuemask |= XpmAllocCloseColors;
3908#else /* not XpmAllocCloseColors */
3909  attrs.closeness = 600;
3910  attrs.valuemask |= XpmCloseness;
3911#endif /* not XpmAllocCloseColors */
3912#endif /* ALLOC_XPM_COLORS */
3913#ifdef ALLOC_XPM_COLORS
3914  xpm_init_color_cache (f, &attrs);
3915#endif
3916
3917  /* If image specification contains symbolic color definitions, add
3918     these to `attrs'.  */
3919  color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL);
3920  if (CONSP (color_symbols))
3921    {
3922      Lisp_Object tail;
3923      XpmColorSymbol *xpm_syms;
3924      int i, size;
3925
3926      attrs.valuemask |= XpmColorSymbols;
3927
3928      /* Count number of symbols.  */
3929      attrs.numsymbols = 0;
3930      for (tail = color_symbols; CONSP (tail); tail = XCDR (tail))
3931	++attrs.numsymbols;
3932
3933      /* Allocate an XpmColorSymbol array.  */
3934      size = attrs.numsymbols * sizeof *xpm_syms;
3935      xpm_syms = (XpmColorSymbol *) alloca (size);
3936      bzero (xpm_syms, size);
3937      attrs.colorsymbols = xpm_syms;
3938
3939      /* Fill the color symbol array.  */
3940      for (tail = color_symbols, i = 0;
3941	   CONSP (tail);
3942	   ++i, tail = XCDR (tail))
3943	{
3944	  Lisp_Object name = XCAR (XCAR (tail));
3945	  Lisp_Object color = XCDR (XCAR (tail));
3946	  xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1);
3947	  strcpy (xpm_syms[i].name, SDATA (name));
3948	  xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1);
3949	  strcpy (xpm_syms[i].value, SDATA (color));
3950	}
3951    }
3952
3953  /* Create a pixmap for the image, either from a file, or from a
3954     string buffer containing data in the same format as an XPM file.  */
3955#ifdef ALLOC_XPM_COLORS
3956  xpm_init_color_cache (f, &attrs);
3957#endif
3958
3959  specified_file = image_spec_value (img->spec, QCfile, NULL);
3960
3961#ifdef HAVE_NTGUI
3962  {
3963    HDC frame_dc = get_frame_dc (f);
3964    hdc = CreateCompatibleDC (frame_dc);
3965    release_frame_dc (f, frame_dc);
3966  }
3967#endif /* HAVE_NTGUI */
3968
3969  if (STRINGP (specified_file))
3970    {
3971      Lisp_Object file = x_find_image_file (specified_file);
3972      if (!STRINGP (file))
3973	{
3974	  image_error ("Cannot find image file `%s'", specified_file, Qnil);
3975	  return 0;
3976	}
3977
3978#ifdef HAVE_NTGUI
3979      /* XpmReadFileToPixmap is not available in the Windows port of
3980	 libxpm.  But XpmReadFileToImage almost does what we want.  */
3981      rc = fn_XpmReadFileToImage (&hdc, SDATA (file),
3982				  &xpm_image, &xpm_mask,
3983				  &attrs);
3984#else
3985      rc = XpmReadFileToPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3986				SDATA (file), &img->pixmap, &img->mask,
3987				&attrs);
3988#endif /* HAVE_NTGUI */
3989    }
3990  else
3991    {
3992      Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);
3993#ifdef HAVE_NTGUI
3994      /* XpmCreatePixmapFromBuffer is not available in the Windows port
3995	 of libxpm.  But XpmCreateImageFromBuffer almost does what we want.  */
3996      rc = fn_XpmCreateImageFromBuffer (&hdc, SDATA (buffer),
3997					&xpm_image, &xpm_mask,
3998					&attrs);
3999#else
4000      rc = XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4001				      SDATA (buffer),
4002				      &img->pixmap, &img->mask,
4003				      &attrs);
4004#endif /* HAVE_NTGUI */
4005    }
4006
4007  if (rc == XpmSuccess)
4008    {
4009#if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS)
4010      img->colors = colors_in_color_table (&img->ncolors);
4011#else /* not ALLOC_XPM_COLORS */
4012      int i;
4013
4014#ifdef HAVE_NTGUI
4015      /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
4016	 plus some duplicate attributes.  */
4017      if (xpm_image && xpm_image->bitmap)
4018	{
4019	  img->pixmap = xpm_image->bitmap;
4020	  /* XImageFree in libXpm frees XImage struct without destroying
4021	     the bitmap, which is what we want.  */
4022	  fn_XImageFree (xpm_image);
4023	}
4024      if (xpm_mask && xpm_mask->bitmap)
4025	{
4026	  /* The mask appears to be inverted compared with what we expect.
4027	     TODO: invert our expectations.  See other places where we
4028	     have to invert bits because our idea of masks is backwards.  */
4029	  HGDIOBJ old_obj;
4030	  old_obj = SelectObject (hdc, xpm_mask->bitmap);
4031
4032	  PatBlt (hdc, 0, 0, xpm_mask->width, xpm_mask->height, DSTINVERT);
4033	  SelectObject (hdc, old_obj);
4034
4035	  img->mask = xpm_mask->bitmap;
4036	  fn_XImageFree (xpm_mask);
4037	  DeleteDC (hdc);
4038	}
4039
4040      DeleteDC (hdc);
4041#endif /* HAVE_NTGUI */
4042
4043      /* Remember allocated colors.  */
4044      img->ncolors = attrs.nalloc_pixels;
4045      img->colors = (unsigned long *) xmalloc (img->ncolors
4046					       * sizeof *img->colors);
4047      for (i = 0; i < attrs.nalloc_pixels; ++i)
4048	{
4049	  img->colors[i] = attrs.alloc_pixels[i];
4050#ifdef DEBUG_X_COLORS
4051	  register_color (img->colors[i]);
4052#endif
4053	}
4054#endif /* not ALLOC_XPM_COLORS */
4055
4056      img->width = attrs.width;
4057      img->height = attrs.height;
4058      xassert (img->width > 0 && img->height > 0);
4059
4060      /* The call to XpmFreeAttributes below frees attrs.alloc_pixels.  */
4061#ifdef HAVE_NTGUI
4062      fn_XpmFreeAttributes (&attrs);
4063#else
4064      XpmFreeAttributes (&attrs);
4065#endif /* HAVE_NTGUI */
4066    }
4067  else
4068    {
4069#ifdef HAVE_NTGUI
4070      DeleteDC (hdc);
4071#endif /* HAVE_NTGUI */
4072
4073      switch (rc)
4074	{
4075	case XpmOpenFailed:
4076	  image_error ("Error opening XPM file (%s)", img->spec, Qnil);
4077	  break;
4078
4079	case XpmFileInvalid:
4080	  image_error ("Invalid XPM file (%s)", img->spec, Qnil);
4081	  break;
4082
4083	case XpmNoMemory:
4084	  image_error ("Out of memory (%s)", img->spec, Qnil);
4085	  break;
4086
4087	case XpmColorFailed:
4088	  image_error ("Color allocation error (%s)", img->spec, Qnil);
4089	  break;
4090
4091	default:
4092	  image_error ("Unknown error (%s)", img->spec, Qnil);
4093	  break;
4094	}
4095    }
4096
4097#ifdef ALLOC_XPM_COLORS
4098  xpm_free_color_cache ();
4099#endif
4100  return rc == XpmSuccess;
4101}
4102
4103#endif /* HAVE_XPM */
4104
4105#ifdef MAC_OS
4106
4107/* XPM support functions for Mac OS where libxpm is not available.
4108   Only XPM version 3 (without any extensions) is supported.  */
4109
4110static int xpm_scan P_ ((const unsigned char **, const unsigned char *,
4111			 const unsigned char **, int *));
4112static Lisp_Object xpm_make_color_table_v
4113  P_ ((void (**) (Lisp_Object, const unsigned char *, int, Lisp_Object),
4114       Lisp_Object (**) (Lisp_Object, const unsigned char *, int)));
4115static void xpm_put_color_table_v P_ ((Lisp_Object, const unsigned char *,
4116				       int, Lisp_Object));
4117static Lisp_Object xpm_get_color_table_v P_ ((Lisp_Object,
4118					      const unsigned char *, int));
4119static Lisp_Object xpm_make_color_table_h
4120  P_ ((void (**) (Lisp_Object, const unsigned char *, int, Lisp_Object),
4121       Lisp_Object (**) (Lisp_Object, const unsigned char *, int)));
4122static void xpm_put_color_table_h P_ ((Lisp_Object, const unsigned char *,
4123				       int, Lisp_Object));
4124static Lisp_Object xpm_get_color_table_h P_ ((Lisp_Object,
4125					      const unsigned char *, int));
4126static int xpm_str_to_color_key P_ ((const char *));
4127static int xpm_load_image P_ ((struct frame *, struct image *,
4128			       const unsigned char *, const unsigned char *));
4129
4130/* Tokens returned from xpm_scan.  */
4131
4132enum xpm_token
4133{
4134  XPM_TK_IDENT = 256,
4135  XPM_TK_STRING,
4136  XPM_TK_EOF
4137};
4138
4139/* Scan an XPM data and return a character (< 256) or a token defined
4140   by enum xpm_token above.  *S and END are the start (inclusive) and
4141   the end (exclusive) addresses of the data, respectively.  Advance
4142   *S while scanning.  If token is either XPM_TK_IDENT or
4143   XPM_TK_STRING, *BEG and *LEN are set to the start address and the
4144   length of the corresponding token, respectively.  */
4145
4146static int
4147xpm_scan (s, end, beg, len)
4148     const unsigned char **s, *end, **beg;
4149     int *len;
4150{
4151  int c;
4152
4153  while (*s < end)
4154    {
4155      /* Skip white-space.  */
4156      while (*s < end && (c = *(*s)++, isspace (c)))
4157	;
4158
4159      /* gnus-pointer.xpm uses '-' in its identifier.
4160	 sb-dir-plus.xpm uses '+' in its identifier.  */
4161      if (isalpha (c) || c == '_' || c == '-' || c == '+')
4162	{
4163	  *beg = *s - 1;
4164	  while (*s < end &&
4165		 (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+'))
4166	      ++*s;
4167	  *len = *s - *beg;
4168	  return XPM_TK_IDENT;
4169	}
4170      else if (c == '"')
4171	{
4172	  *beg = *s;
4173	  while (*s < end && **s != '"')
4174	    ++*s;
4175	  *len = *s - *beg;
4176	  if (*s < end)
4177	    ++*s;
4178	  return XPM_TK_STRING;
4179	}
4180      else if (c == '/')
4181	{
4182	  if (*s < end && **s == '*')
4183	    {
4184	      /* C-style comment.  */
4185	      ++*s;
4186	      do
4187		{
4188		  while (*s < end && *(*s)++ != '*')
4189		    ;
4190		}
4191	      while (*s < end && **s != '/');
4192	      if (*s < end)
4193		++*s;
4194	    }
4195	  else
4196	    return c;
4197	}
4198      else
4199	return c;
4200    }
4201
4202  return XPM_TK_EOF;
4203}
4204
4205/* Functions for color table lookup in XPM data.  A Key is a string
4206   specifying the color of each pixel in XPM data.  A value is either
4207   an integer that specifies a pixel color, Qt that specifies
4208   transparency, or Qnil for the unspecified color.  If the length of
4209   the key string is one, a vector is used as a table.  Otherwise, a
4210   hash table is used.  */
4211
4212static Lisp_Object
4213xpm_make_color_table_v (put_func, get_func)
4214     void (**put_func) (Lisp_Object, const unsigned char *, int, Lisp_Object);
4215     Lisp_Object (**get_func) (Lisp_Object, const unsigned char *, int);
4216{
4217  *put_func = xpm_put_color_table_v;
4218  *get_func = xpm_get_color_table_v;
4219  return Fmake_vector (make_number (256), Qnil);
4220}
4221
4222static void
4223xpm_put_color_table_v (color_table, chars_start, chars_len, color)
4224     Lisp_Object color_table;
4225     const unsigned char *chars_start;
4226     int chars_len;
4227     Lisp_Object color;
4228{
4229  XVECTOR (color_table)->contents[*chars_start] = color;
4230}
4231
4232static Lisp_Object
4233xpm_get_color_table_v (color_table, chars_start, chars_len)
4234     Lisp_Object color_table;
4235     const unsigned char *chars_start;
4236     int chars_len;
4237{
4238  return XVECTOR (color_table)->contents[*chars_start];
4239}
4240
4241static Lisp_Object
4242xpm_make_color_table_h (put_func, get_func)
4243     void (**put_func) (Lisp_Object, const unsigned char *, int, Lisp_Object);
4244     Lisp_Object (**get_func) (Lisp_Object, const unsigned char *, int);
4245{
4246  *put_func = xpm_put_color_table_h;
4247  *get_func = xpm_get_color_table_h;
4248  return make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE),
4249			  make_float (DEFAULT_REHASH_SIZE),
4250			  make_float (DEFAULT_REHASH_THRESHOLD),
4251			  Qnil, Qnil, Qnil);
4252}
4253
4254static void
4255xpm_put_color_table_h (color_table, chars_start, chars_len, color)
4256     Lisp_Object color_table;
4257     const unsigned char *chars_start;
4258     int chars_len;
4259     Lisp_Object color;
4260{
4261  struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
4262  unsigned hash_code;
4263  Lisp_Object chars = make_unibyte_string (chars_start, chars_len);
4264
4265  hash_lookup (table, chars, &hash_code);
4266  hash_put (table, chars, color, hash_code);
4267}
4268
4269static Lisp_Object
4270xpm_get_color_table_h (color_table, chars_start, chars_len)
4271     Lisp_Object color_table;
4272     const unsigned char *chars_start;
4273     int chars_len;
4274{
4275  struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
4276  int i = hash_lookup (table, make_unibyte_string (chars_start, chars_len),
4277		       NULL);
4278
4279  return i >= 0 ? HASH_VALUE (table, i) : Qnil;
4280}
4281
4282enum xpm_color_key {
4283  XPM_COLOR_KEY_S,
4284  XPM_COLOR_KEY_M,
4285  XPM_COLOR_KEY_G4,
4286  XPM_COLOR_KEY_G,
4287  XPM_COLOR_KEY_C
4288};
4289
4290static const char xpm_color_key_strings[][4] = {"s", "m", "g4", "g", "c"};
4291
4292static int
4293xpm_str_to_color_key (s)
4294     const char *s;
4295{
4296  int i;
4297
4298  for (i = 0;
4299       i < sizeof xpm_color_key_strings / sizeof xpm_color_key_strings[0];
4300       i++)
4301    if (strcmp (xpm_color_key_strings[i], s) == 0)
4302      return i;
4303  return -1;
4304}
4305
4306static int
4307xpm_load_image (f, img, contents, end)
4308     struct frame *f;
4309     struct image *img;
4310     const unsigned char *contents, *end;
4311{
4312  const unsigned char *s = contents, *beg, *str;
4313  unsigned char buffer[BUFSIZ];
4314  int width, height, x, y;
4315  int num_colors, chars_per_pixel;
4316  int len, LA1;
4317  void (*put_color_table) (Lisp_Object, const unsigned char *, int, Lisp_Object);
4318  Lisp_Object (*get_color_table) (Lisp_Object, const unsigned char *, int);
4319  Lisp_Object frame, color_symbols, color_table;
4320  int best_key, have_mask = 0;
4321  XImagePtr ximg = NULL, mask_img = NULL;
4322
4323#define match() \
4324     LA1 = xpm_scan (&s, end, &beg, &len)
4325
4326#define expect(TOKEN)		\
4327     if (LA1 != (TOKEN)) 	\
4328       goto failure;		\
4329     else			\
4330       match ()
4331
4332#define expect_ident(IDENT)					\
4333     if (LA1 == XPM_TK_IDENT \
4334         && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0)	\
4335       match ();						\
4336     else							\
4337       goto failure
4338
4339  if (!(end - s >= 9 && memcmp (s, "/* XPM */", 9) == 0))
4340    goto failure;
4341  s += 9;
4342  match();
4343  expect_ident ("static");
4344  expect_ident ("char");
4345  expect ('*');
4346  expect (XPM_TK_IDENT);
4347  expect ('[');
4348  expect (']');
4349  expect ('=');
4350  expect ('{');
4351  expect (XPM_TK_STRING);
4352  if (len >= BUFSIZ)
4353    goto failure;
4354  memcpy (buffer, beg, len);
4355  buffer[len] = '\0';
4356  if (sscanf (buffer, "%d %d %d %d", &width, &height,
4357	      &num_colors, &chars_per_pixel) != 4
4358      || width <= 0 || height <= 0
4359      || num_colors <= 0 || chars_per_pixel <= 0)
4360    goto failure;
4361
4362  if (!check_image_size (f, width, height))
4363    {
4364      image_error ("Invalid image size", Qnil, Qnil);
4365      goto failure;
4366    }
4367
4368  expect (',');
4369
4370  XSETFRAME (frame, f);
4371  if (!NILP (Fxw_display_color_p (frame)))
4372    best_key = XPM_COLOR_KEY_C;
4373  else if (!NILP (Fx_display_grayscale_p (frame)))
4374    best_key = (XFASTINT (Fx_display_planes (frame)) > 2
4375		? XPM_COLOR_KEY_G : XPM_COLOR_KEY_G4);
4376  else
4377    best_key = XPM_COLOR_KEY_M;
4378
4379  color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL);
4380  if (chars_per_pixel == 1)
4381    color_table = xpm_make_color_table_v (&put_color_table,
4382					  &get_color_table);
4383  else
4384    color_table = xpm_make_color_table_h (&put_color_table,
4385					  &get_color_table);
4386
4387  while (num_colors-- > 0)
4388    {
4389      unsigned char *color, *max_color;
4390      int key, next_key, max_key = 0;
4391      Lisp_Object symbol_color = Qnil, color_val;
4392      XColor cdef;
4393
4394      expect (XPM_TK_STRING);
4395      if (len <= chars_per_pixel || len >= BUFSIZ + chars_per_pixel)
4396	goto failure;
4397      memcpy (buffer, beg + chars_per_pixel, len - chars_per_pixel);
4398      buffer[len - chars_per_pixel] = '\0';
4399
4400      str = strtok (buffer, " \t");
4401      if (str == NULL)
4402	goto failure;
4403      key = xpm_str_to_color_key (str);
4404      if (key < 0)
4405	goto failure;
4406      do
4407	{
4408	  color = strtok (NULL, " \t");
4409	  if (color == NULL)
4410	    goto failure;
4411
4412	  while ((str = strtok (NULL, " \t")) != NULL)
4413	    {
4414	      next_key = xpm_str_to_color_key (str);
4415	      if (next_key >= 0)
4416		break;
4417	      color[strlen (color)] = ' ';
4418	    }
4419
4420	  if (key == XPM_COLOR_KEY_S)
4421	    {
4422	      if (NILP (symbol_color))
4423		symbol_color = build_string (color);
4424	    }
4425	  else if (max_key < key && key <= best_key)
4426	    {
4427	      max_key = key;
4428	      max_color = color;
4429	    }
4430	  key = next_key;
4431	}
4432      while (str);
4433
4434      color_val = Qnil;
4435      if (!NILP (color_symbols) && !NILP (symbol_color))
4436	{
4437	  Lisp_Object specified_color = Fassoc (symbol_color, color_symbols);
4438
4439	  if (CONSP (specified_color) && STRINGP (XCDR (specified_color)))
4440	    {
4441	      if (xstricmp (SDATA (XCDR (specified_color)), "None") == 0)
4442		color_val = Qt;
4443	      else if (x_defined_color (f, SDATA (XCDR (specified_color)),
4444					&cdef, 0))
4445		color_val = make_number (cdef.pixel);
4446	    }
4447	}
4448      if (NILP (color_val) && max_key > 0)
4449	{
4450	  if (xstricmp (max_color, "None") == 0)
4451	    color_val = Qt;
4452	  else if (x_defined_color (f, max_color, &cdef, 0))
4453	    color_val = make_number (cdef.pixel);
4454	}
4455      if (!NILP (color_val))
4456	(*put_color_table) (color_table, beg, chars_per_pixel, color_val);
4457
4458      expect (',');
4459    }
4460
4461  if (!x_create_x_image_and_pixmap (f, width, height, 0,
4462				    &ximg, &img->pixmap)
4463      || !x_create_x_image_and_pixmap (f, width, height, 1,
4464				       &mask_img, &img->mask))
4465    {
4466      image_error ("Out of memory (%s)", img->spec, Qnil);
4467      goto error;
4468    }
4469
4470  for (y = 0; y < height; y++)
4471    {
4472      expect (XPM_TK_STRING);
4473      str = beg;
4474      if (len < width * chars_per_pixel)
4475	goto failure;
4476      for (x = 0; x < width; x++, str += chars_per_pixel)
4477	{
4478	  Lisp_Object color_val =
4479	    (*get_color_table) (color_table, str, chars_per_pixel);
4480
4481	  XPutPixel (ximg, x, y,
4482		     (INTEGERP (color_val) ? XINT (color_val)
4483		      : FRAME_FOREGROUND_PIXEL (f)));
4484	  XPutPixel (mask_img, x, y,
4485		     (!EQ (color_val, Qt) ? PIX_MASK_DRAW
4486		      : (have_mask = 1, PIX_MASK_RETAIN)));
4487	}
4488      if (y + 1 < height)
4489	expect (',');
4490    }
4491
4492  img->width = width;
4493  img->height = height;
4494
4495  /* Maybe fill in the background field while we have ximg handy. */
4496  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
4497    IMAGE_BACKGROUND (img, f, ximg);
4498
4499  x_put_x_image (f, ximg, img->pixmap, width, height);
4500  x_destroy_x_image (ximg);
4501  if (have_mask)
4502    {
4503      /* Fill in the background_transparent field while we have the
4504	 mask handy.  */
4505      image_background_transparent (img, f, mask_img);
4506
4507      x_put_x_image (f, mask_img, img->mask, width, height);
4508      x_destroy_x_image (mask_img);
4509    }
4510  else
4511    {
4512      x_destroy_x_image (mask_img);
4513      Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
4514      img->mask = NO_PIXMAP;
4515    }
4516
4517  return 1;
4518
4519 failure:
4520  image_error ("Invalid XPM file (%s)", img->spec, Qnil);
4521 error:
4522  x_destroy_x_image (ximg);
4523  x_destroy_x_image (mask_img);
4524  x_clear_image (f, img);
4525  return 0;
4526
4527#undef match
4528#undef expect
4529#undef expect_ident
4530}
4531
4532static int
4533xpm_load (f, img)
4534     struct frame *f;
4535     struct image *img;
4536{
4537  int success_p = 0;
4538  Lisp_Object file_name;
4539
4540  /* If IMG->spec specifies a file name, create a non-file spec from it.  */
4541  file_name = image_spec_value (img->spec, QCfile, NULL);
4542  if (STRINGP (file_name))
4543    {
4544      Lisp_Object file;
4545      unsigned char *contents;
4546      int size;
4547      struct gcpro gcpro1;
4548
4549      file = x_find_image_file (file_name);
4550      GCPRO1 (file);
4551      if (!STRINGP (file))
4552	{
4553	  image_error ("Cannot find image file `%s'", file_name, Qnil);
4554	  UNGCPRO;
4555	  return 0;
4556	}
4557
4558      contents = slurp_file (SDATA (file), &size);
4559      if (contents == NULL)
4560	{
4561	  image_error ("Error loading XPM image `%s'", img->spec, Qnil);
4562	  UNGCPRO;
4563	  return 0;
4564	}
4565
4566      success_p = xpm_load_image (f, img, contents, contents + size);
4567      xfree (contents);
4568      UNGCPRO;
4569    }
4570  else
4571    {
4572      Lisp_Object data;
4573
4574      data = image_spec_value (img->spec, QCdata, NULL);
4575      success_p = xpm_load_image (f, img, SDATA (data),
4576				  SDATA (data) + SBYTES (data));
4577    }
4578
4579  return success_p;
4580}
4581
4582#endif /* MAC_OS */
4583
4584
4585
4586/***********************************************************************
4587			     Color table
4588 ***********************************************************************/
4589
4590#ifdef COLOR_TABLE_SUPPORT
4591
4592/* An entry in the color table mapping an RGB color to a pixel color.  */
4593
4594struct ct_color
4595{
4596  int r, g, b;
4597  unsigned long pixel;
4598
4599  /* Next in color table collision list.  */
4600  struct ct_color *next;
4601};
4602
4603/* The bucket vector size to use.  Must be prime.  */
4604
4605#define CT_SIZE 101
4606
4607/* Value is a hash of the RGB color given by R, G, and B.  */
4608
4609#define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
4610
4611/* The color hash table.  */
4612
4613struct ct_color **ct_table;
4614
4615/* Number of entries in the color table.  */
4616
4617int ct_colors_allocated;
4618
4619/* Initialize the color table.  */
4620
4621static void
4622init_color_table ()
4623{
4624  int size = CT_SIZE * sizeof (*ct_table);
4625  ct_table = (struct ct_color **) xmalloc (size);
4626  bzero (ct_table, size);
4627  ct_colors_allocated = 0;
4628}
4629
4630
4631/* Free memory associated with the color table.  */
4632
4633static void
4634free_color_table ()
4635{
4636  int i;
4637  struct ct_color *p, *next;
4638
4639  for (i = 0; i < CT_SIZE; ++i)
4640    for (p = ct_table[i]; p; p = next)
4641      {
4642	next = p->next;
4643	xfree (p);
4644      }
4645
4646  xfree (ct_table);
4647  ct_table = NULL;
4648}
4649
4650
4651/* Value is a pixel color for RGB color R, G, B on frame F.  If an
4652   entry for that color already is in the color table, return the
4653   pixel color of that entry.  Otherwise, allocate a new color for R,
4654   G, B, and make an entry in the color table.  */
4655
4656static unsigned long
4657lookup_rgb_color (f, r, g, b)
4658     struct frame *f;
4659     int r, g, b;
4660{
4661  unsigned hash = CT_HASH_RGB (r, g, b);
4662  int i = hash % CT_SIZE;
4663  struct ct_color *p;
4664  Display_Info *dpyinfo;
4665
4666  /* Handle TrueColor visuals specially, which improves performance by
4667     two orders of magnitude.  Freeing colors on TrueColor visuals is
4668     a nop, and pixel colors specify RGB values directly.  See also
4669     the Xlib spec, chapter 3.1.  */
4670  dpyinfo = FRAME_X_DISPLAY_INFO (f);
4671  if (dpyinfo->red_bits > 0)
4672    {
4673      unsigned long pr, pg, pb;
4674
4675      /* Apply gamma-correction like normal color allocation does.  */
4676      if (f->gamma)
4677	{
4678	  XColor color;
4679	  color.red = r, color.green = g, color.blue = b;
4680	  gamma_correct (f, &color);
4681	  r = color.red, g = color.green, b = color.blue;
4682	}
4683
4684      /* Scale down RGB values to the visual's bits per RGB, and shift
4685	 them to the right position in the pixel color.  Note that the
4686	 original RGB values are 16-bit values, as usual in X.  */
4687      pr = (r >> (16 - dpyinfo->red_bits))   << dpyinfo->red_offset;
4688      pg = (g >> (16 - dpyinfo->green_bits)) << dpyinfo->green_offset;
4689      pb = (b >> (16 - dpyinfo->blue_bits))  << dpyinfo->blue_offset;
4690
4691      /* Assemble the pixel color.  */
4692      return pr | pg | pb;
4693    }
4694
4695  for (p = ct_table[i]; p; p = p->next)
4696    if (p->r == r && p->g == g && p->b == b)
4697      break;
4698
4699  if (p == NULL)
4700    {
4701
4702#ifdef HAVE_X_WINDOWS
4703      XColor color;
4704      Colormap cmap;
4705      int rc;
4706
4707      color.red = r;
4708      color.green = g;
4709      color.blue = b;
4710
4711      cmap = FRAME_X_COLORMAP (f);
4712      rc = x_alloc_nearest_color (f, cmap, &color);
4713      if (rc)
4714	{
4715	  ++ct_colors_allocated;
4716	  p = (struct ct_color *) xmalloc (sizeof *p);
4717	  p->r = r;
4718	  p->g = g;
4719	  p->b = b;
4720	  p->pixel = color.pixel;
4721	  p->next = ct_table[i];
4722	  ct_table[i] = p;
4723	}
4724      else
4725	return FRAME_FOREGROUND_PIXEL (f);
4726
4727#else
4728      COLORREF color;
4729#ifdef HAVE_NTGUI
4730      color = PALETTERGB (r, g, b);
4731#else
4732      color = RGB_TO_ULONG (r, g, b);
4733#endif /* HAVE_NTGUI */
4734      ++ct_colors_allocated;
4735      p = (struct ct_color *) xmalloc (sizeof *p);
4736      p->r = r;
4737      p->g = g;
4738      p->b = b;
4739      p->pixel = color;
4740      p->next = ct_table[i];
4741      ct_table[i] = p;
4742#endif /* HAVE_X_WINDOWS */
4743
4744    }
4745
4746  return p->pixel;
4747}
4748
4749
4750/* Look up pixel color PIXEL which is used on frame F in the color
4751   table.  If not already present, allocate it.  Value is PIXEL.  */
4752
4753static unsigned long
4754lookup_pixel_color (f, pixel)
4755     struct frame *f;
4756     unsigned long pixel;
4757{
4758  int i = pixel % CT_SIZE;
4759  struct ct_color *p;
4760
4761  for (p = ct_table[i]; p; p = p->next)
4762    if (p->pixel == pixel)
4763      break;
4764
4765  if (p == NULL)
4766    {
4767      XColor color;
4768      Colormap cmap;
4769      int rc;
4770
4771#ifdef HAVE_X_WINDOWS
4772      cmap = FRAME_X_COLORMAP (f);
4773      color.pixel = pixel;
4774      x_query_color (f, &color);
4775      rc = x_alloc_nearest_color (f, cmap, &color);
4776#else
4777      BLOCK_INPUT;
4778      cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f));
4779      color.pixel = pixel;
4780      XQueryColor (NULL, cmap, &color);
4781      rc = x_alloc_nearest_color (f, cmap, &color);
4782      UNBLOCK_INPUT;
4783#endif /* HAVE_X_WINDOWS */
4784
4785      if (rc)
4786	{
4787	  ++ct_colors_allocated;
4788
4789	  p = (struct ct_color *) xmalloc (sizeof *p);
4790	  p->r = color.red;
4791	  p->g = color.green;
4792	  p->b = color.blue;
4793	  p->pixel = pixel;
4794	  p->next = ct_table[i];
4795	  ct_table[i] = p;
4796	}
4797      else
4798	return FRAME_FOREGROUND_PIXEL (f);
4799    }
4800  return p->pixel;
4801}
4802
4803
4804/* Value is a vector of all pixel colors contained in the color table,
4805   allocated via xmalloc.  Set *N to the number of colors.  */
4806
4807static unsigned long *
4808colors_in_color_table (n)
4809     int *n;
4810{
4811  int i, j;
4812  struct ct_color *p;
4813  unsigned long *colors;
4814
4815  if (ct_colors_allocated == 0)
4816    {
4817      *n = 0;
4818      colors = NULL;
4819    }
4820  else
4821    {
4822      colors = (unsigned long *) xmalloc (ct_colors_allocated
4823					  * sizeof *colors);
4824      *n = ct_colors_allocated;
4825
4826      for (i = j = 0; i < CT_SIZE; ++i)
4827	for (p = ct_table[i]; p; p = p->next)
4828	  colors[j++] = p->pixel;
4829    }
4830
4831  return colors;
4832}
4833
4834#else /* COLOR_TABLE_SUPPORT */
4835
4836static unsigned long
4837lookup_rgb_color (f, r, g, b)
4838     struct frame *f;
4839     int r, g, b;
4840{
4841  unsigned long pixel;
4842
4843#ifdef MAC_OS
4844  pixel = RGB_TO_ULONG (r >> 8, g >> 8, b >> 8);
4845  gamma_correct (f, &pixel);
4846#endif /* MAC_OS */
4847
4848#ifdef HAVE_NTGUI
4849  pixel = PALETTERGB (r >> 8, g >> 8, b >> 8);
4850#endif /* HAVE_NTGUI */
4851
4852  return pixel;
4853}
4854
4855static void
4856init_color_table ()
4857{
4858}
4859#endif /* COLOR_TABLE_SUPPORT */
4860
4861
4862/***********************************************************************
4863			      Algorithms
4864 ***********************************************************************/
4865
4866static XColor *x_to_xcolors P_ ((struct frame *, struct image *, int));
4867static void x_from_xcolors P_ ((struct frame *, struct image *, XColor *));
4868static void x_detect_edges P_ ((struct frame *, struct image *, int[9], int));
4869
4870#ifdef HAVE_NTGUI
4871static void XPutPixel (XImagePtr , int, int, COLORREF);
4872#endif /* HAVE_NTGUI */
4873
4874/* Non-zero means draw a cross on images having `:conversion
4875   disabled'.  */
4876
4877int cross_disabled_images;
4878
4879/* Edge detection matrices for different edge-detection
4880   strategies.  */
4881
4882static int emboss_matrix[9] = {
4883   /* x - 1	x	x + 1  */
4884        2,     -1,  	  0,		/* y - 1 */
4885       -1,      0,        1,		/* y     */
4886        0,      1,       -2		/* y + 1 */
4887};
4888
4889static int laplace_matrix[9] = {
4890   /* x - 1	x	x + 1  */
4891        1,      0,  	  0,		/* y - 1 */
4892        0,      0,        0,		/* y     */
4893        0,      0,       -1		/* y + 1 */
4894};
4895
4896/* Value is the intensity of the color whose red/green/blue values
4897   are R, G, and B.  */
4898
4899#define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
4900
4901
4902/* On frame F, return an array of XColor structures describing image
4903   IMG->pixmap.  Each XColor structure has its pixel color set.  RGB_P
4904   non-zero means also fill the red/green/blue members of the XColor
4905   structures.  Value is a pointer to the array of XColors structures,
4906   allocated with xmalloc; it must be freed by the caller.  */
4907
4908static XColor *
4909x_to_xcolors (f, img, rgb_p)
4910     struct frame *f;
4911     struct image *img;
4912     int rgb_p;
4913{
4914  int x, y;
4915  XColor *colors, *p;
4916  XImagePtr_or_DC ximg;
4917#ifdef HAVE_NTGUI
4918  HDC hdc;
4919  HGDIOBJ prev;
4920#endif /* HAVE_NTGUI */
4921
4922  colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors);
4923
4924#ifndef HAVE_NTGUI
4925  /* Get the X image IMG->pixmap.  */
4926  ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
4927		    0, 0, img->width, img->height, ~0, ZPixmap);
4928#else
4929  /* Load the image into a memory device context.  */
4930  hdc = get_frame_dc (f);
4931  ximg = CreateCompatibleDC (hdc);
4932  release_frame_dc (f, hdc);
4933  prev = SelectObject (ximg, img->pixmap);
4934#endif /* HAVE_NTGUI */
4935
4936  /* Fill the `pixel' members of the XColor array.  I wished there
4937     were an easy and portable way to circumvent XGetPixel.  */
4938  p = colors;
4939  for (y = 0; y < img->height; ++y)
4940    {
4941      XColor *row = p;
4942
4943#ifdef HAVE_X_WINDOWS
4944      for (x = 0; x < img->width; ++x, ++p)
4945	p->pixel = XGetPixel (ximg, x, y);
4946      if (rgb_p)
4947	x_query_colors (f, row, img->width);
4948
4949#else
4950
4951      for (x = 0; x < img->width; ++x, ++p)
4952	{
4953	  /* W32_TODO: palette support needed here?  */
4954	  p->pixel = GET_PIXEL (ximg, x, y);
4955	  if (rgb_p)
4956	    {
4957#ifdef MAC_OS
4958	      p->red = RED16_FROM_ULONG (p->pixel);
4959	      p->green = GREEN16_FROM_ULONG (p->pixel);
4960	      p->blue = BLUE16_FROM_ULONG (p->pixel);
4961#endif  /* MAC_OS */
4962#ifdef HAVE_NTGUI
4963	      p->red = 256 * GetRValue (p->pixel);
4964	      p->green = 256 * GetGValue (p->pixel);
4965	      p->blue = 256 * GetBValue (p->pixel);
4966#endif /* HAVE_NTGUI */
4967	    }
4968	}
4969#endif /* HAVE_X_WINDOWS */
4970    }
4971
4972  Destroy_Image (ximg, prev);
4973
4974  return colors;
4975}
4976
4977#ifdef HAVE_NTGUI
4978
4979/* Put a pixel of COLOR at position X, Y in XIMG.  XIMG must have been
4980   created with CreateDIBSection, with the pointer to the bit values
4981   stored in ximg->data.  */
4982
4983static void XPutPixel (ximg, x, y, color)
4984     XImagePtr  ximg;
4985     int x, y;
4986     COLORREF color;
4987{
4988  int width = ximg->info.bmiHeader.biWidth;
4989  int height = ximg->info.bmiHeader.biHeight;
4990  unsigned char * pixel;
4991
4992  /* True color images.  */
4993  if (ximg->info.bmiHeader.biBitCount == 24)
4994    {
4995      int rowbytes = width * 3;
4996      /* Ensure scanlines are aligned on 4 byte boundaries.  */
4997      if (rowbytes % 4)
4998	rowbytes += 4 - (rowbytes % 4);
4999
5000      pixel = ximg->data + y * rowbytes + x * 3;
5001      /* Windows bitmaps are in BGR order.  */
5002      *pixel = GetBValue (color);
5003      *(pixel + 1) = GetGValue (color);
5004      *(pixel + 2) = GetRValue (color);
5005    }
5006  /* Monochrome images.  */
5007  else if (ximg->info.bmiHeader.biBitCount == 1)
5008    {
5009      int rowbytes = width / 8;
5010      /* Ensure scanlines are aligned on 4 byte boundaries.  */
5011      if (rowbytes % 4)
5012	rowbytes += 4 - (rowbytes % 4);
5013      pixel = ximg->data + y * rowbytes + x / 8;
5014      /* Filter out palette info.  */
5015      if (color & 0x00ffffff)
5016	*pixel = *pixel | (1 << x % 8);
5017      else
5018	*pixel = *pixel & ~(1 << x % 8);
5019    }
5020  else
5021    image_error ("XPutPixel: palette image not supported", Qnil, Qnil);
5022}
5023
5024#endif /* HAVE_NTGUI */
5025
5026/* Create IMG->pixmap from an array COLORS of XColor structures, whose
5027   RGB members are set.  F is the frame on which this all happens.
5028   COLORS will be freed; an existing IMG->pixmap will be freed, too.  */
5029
5030static void
5031x_from_xcolors (f, img, colors)
5032     struct frame *f;
5033     struct image *img;
5034     XColor *colors;
5035{
5036  int x, y;
5037  XImagePtr oimg;
5038  Pixmap pixmap;
5039  XColor *p;
5040
5041  init_color_table ();
5042
5043  x_create_x_image_and_pixmap (f, img->width, img->height, 0,
5044			       &oimg, &pixmap);
5045  p = colors;
5046  for (y = 0; y < img->height; ++y)
5047    for (x = 0; x < img->width; ++x, ++p)
5048      {
5049	unsigned long pixel;
5050	pixel = lookup_rgb_color (f, p->red, p->green, p->blue);
5051	XPutPixel (oimg, x, y, pixel);
5052      }
5053
5054  xfree (colors);
5055  x_clear_image_1 (f, img, 1, 0, 1);
5056
5057  x_put_x_image (f, oimg, pixmap, img->width, img->height);
5058  x_destroy_x_image (oimg);
5059  img->pixmap = pixmap;
5060#ifdef COLOR_TABLE_SUPPORT
5061  img->colors = colors_in_color_table (&img->ncolors);
5062  free_color_table ();
5063#endif /* COLOR_TABLE_SUPPORT */
5064}
5065
5066
5067/* On frame F, perform edge-detection on image IMG.
5068
5069   MATRIX is a nine-element array specifying the transformation
5070   matrix.  See emboss_matrix for an example.
5071
5072   COLOR_ADJUST is a color adjustment added to each pixel of the
5073   outgoing image.  */
5074
5075static void
5076x_detect_edges (f, img, matrix, color_adjust)
5077     struct frame *f;
5078     struct image *img;
5079     int matrix[9], color_adjust;
5080{
5081  XColor *colors = x_to_xcolors (f, img, 1);
5082  XColor *new, *p;
5083  int x, y, i, sum;
5084
5085  for (i = sum = 0; i < 9; ++i)
5086    sum += abs (matrix[i]);
5087
5088#define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
5089
5090  new = (XColor *) xmalloc (img->width * img->height * sizeof *new);
5091
5092  for (y = 0; y < img->height; ++y)
5093    {
5094      p = COLOR (new, 0, y);
5095      p->red = p->green = p->blue = 0xffff/2;
5096      p = COLOR (new, img->width - 1, y);
5097      p->red = p->green = p->blue = 0xffff/2;
5098    }
5099
5100  for (x = 1; x < img->width - 1; ++x)
5101    {
5102      p = COLOR (new, x, 0);
5103      p->red = p->green = p->blue = 0xffff/2;
5104      p = COLOR (new, x, img->height - 1);
5105      p->red = p->green = p->blue = 0xffff/2;
5106    }
5107
5108  for (y = 1; y < img->height - 1; ++y)
5109    {
5110      p = COLOR (new, 1, y);
5111
5112      for (x = 1; x < img->width - 1; ++x, ++p)
5113	{
5114	  int r, g, b, y1, x1;
5115
5116	  r = g = b = i = 0;
5117	  for (y1 = y - 1; y1 < y + 2; ++y1)
5118	    for (x1 = x - 1; x1 < x + 2; ++x1, ++i)
5119	      if (matrix[i])
5120	        {
5121	          XColor *t = COLOR (colors, x1, y1);
5122		  r += matrix[i] * t->red;
5123		  g += matrix[i] * t->green;
5124		  b += matrix[i] * t->blue;
5125		}
5126
5127	  r = (r / sum + color_adjust) & 0xffff;
5128	  g = (g / sum + color_adjust) & 0xffff;
5129	  b = (b / sum + color_adjust) & 0xffff;
5130	  p->red = p->green = p->blue = COLOR_INTENSITY (r, g, b);
5131	}
5132    }
5133
5134  xfree (colors);
5135  x_from_xcolors (f, img, new);
5136
5137#undef COLOR
5138}
5139
5140
5141/* Perform the pre-defined `emboss' edge-detection on image IMG
5142   on frame F.  */
5143
5144static void
5145x_emboss (f, img)
5146     struct frame *f;
5147     struct image *img;
5148{
5149  x_detect_edges (f, img, emboss_matrix, 0xffff / 2);
5150}
5151
5152
5153/* Transform image IMG which is used on frame F with a Laplace
5154   edge-detection algorithm.  The result is an image that can be used
5155   to draw disabled buttons, for example.  */
5156
5157static void
5158x_laplace (f, img)
5159     struct frame *f;
5160     struct image *img;
5161{
5162  x_detect_edges (f, img, laplace_matrix, 45000);
5163}
5164
5165
5166/* Perform edge-detection on image IMG on frame F, with specified
5167   transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
5168
5169   MATRIX must be either
5170
5171   - a list of at least 9 numbers in row-major form
5172   - a vector of at least 9 numbers
5173
5174   COLOR_ADJUST nil means use a default; otherwise it must be a
5175   number.  */
5176
5177static void
5178x_edge_detection (f, img, matrix, color_adjust)
5179     struct frame *f;
5180     struct image *img;
5181     Lisp_Object matrix, color_adjust;
5182{
5183  int i = 0;
5184  int trans[9];
5185
5186  if (CONSP (matrix))
5187    {
5188      for (i = 0;
5189	   i < 9 && CONSP (matrix) && NUMBERP (XCAR (matrix));
5190	   ++i, matrix = XCDR (matrix))
5191	trans[i] = XFLOATINT (XCAR (matrix));
5192    }
5193  else if (VECTORP (matrix) && ASIZE (matrix) >= 9)
5194    {
5195      for (i = 0; i < 9 && NUMBERP (AREF (matrix, i)); ++i)
5196	trans[i] = XFLOATINT (AREF (matrix, i));
5197    }
5198
5199  if (NILP (color_adjust))
5200    color_adjust = make_number (0xffff / 2);
5201
5202  if (i == 9 && NUMBERP (color_adjust))
5203    x_detect_edges (f, img, trans, (int) XFLOATINT (color_adjust));
5204}
5205
5206
5207/* Transform image IMG on frame F so that it looks disabled.  */
5208
5209static void
5210x_disable_image (f, img)
5211     struct frame *f;
5212     struct image *img;
5213{
5214  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
5215#ifdef HAVE_NTGUI
5216  int n_planes = dpyinfo->n_planes * dpyinfo->n_cbits;
5217#else
5218  int n_planes = dpyinfo->n_planes;
5219#endif /* HAVE_NTGUI */
5220
5221  if (n_planes >= 2)
5222    {
5223      /* Color (or grayscale).  Convert to gray, and equalize.  Just
5224	 drawing such images with a stipple can look very odd, so
5225	 we're using this method instead.  */
5226      XColor *colors = x_to_xcolors (f, img, 1);
5227      XColor *p, *end;
5228      const int h = 15000;
5229      const int l = 30000;
5230
5231      for (p = colors, end = colors + img->width * img->height;
5232	   p < end;
5233	   ++p)
5234	{
5235	  int i = COLOR_INTENSITY (p->red, p->green, p->blue);
5236	  int i2 = (0xffff - h - l) * i / 0xffff + l;
5237	  p->red = p->green = p->blue = i2;
5238	}
5239
5240      x_from_xcolors (f, img, colors);
5241    }
5242
5243  /* Draw a cross over the disabled image, if we must or if we
5244     should.  */
5245  if (n_planes < 2 || cross_disabled_images)
5246    {
5247#ifndef HAVE_NTGUI
5248      Display *dpy = FRAME_X_DISPLAY (f);
5249      GC gc;
5250
5251#ifdef MAC_OS
5252#define MaskForeground(f)  PIX_MASK_DRAW
5253#else
5254#define MaskForeground(f)  WHITE_PIX_DEFAULT (f)
5255#endif
5256
5257      gc = XCreateGC (dpy, img->pixmap, 0, NULL);
5258      XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f));
5259      XDrawLine (dpy, img->pixmap, gc, 0, 0,
5260		 img->width - 1, img->height - 1);
5261      XDrawLine (dpy, img->pixmap, gc, 0, img->height - 1,
5262		 img->width - 1, 0);
5263      XFreeGC (dpy, gc);
5264
5265      if (img->mask)
5266	{
5267	  gc = XCreateGC (dpy, img->mask, 0, NULL);
5268	  XSetForeground (dpy, gc, MaskForeground (f));
5269	  XDrawLine (dpy, img->mask, gc, 0, 0,
5270		     img->width - 1, img->height - 1);
5271	  XDrawLine (dpy, img->mask, gc, 0, img->height - 1,
5272		     img->width - 1, 0);
5273	  XFreeGC (dpy, gc);
5274	}
5275#else
5276      HDC hdc, bmpdc;
5277      HGDIOBJ prev;
5278
5279      hdc = get_frame_dc (f);
5280      bmpdc = CreateCompatibleDC (hdc);
5281      release_frame_dc (f, hdc);
5282
5283      prev = SelectObject (bmpdc, img->pixmap);
5284
5285      SetTextColor (bmpdc, BLACK_PIX_DEFAULT (f));
5286      MoveToEx (bmpdc, 0, 0, NULL);
5287      LineTo (bmpdc, img->width - 1, img->height - 1);
5288      MoveToEx (bmpdc, 0, img->height - 1, NULL);
5289      LineTo (bmpdc, img->width - 1, 0);
5290
5291      if (img->mask)
5292	{
5293	  SelectObject (bmpdc, img->mask);
5294	  SetTextColor (bmpdc, WHITE_PIX_DEFAULT (f));
5295	  MoveToEx (bmpdc, 0, 0, NULL);
5296	  LineTo (bmpdc, img->width - 1, img->height - 1);
5297	  MoveToEx (bmpdc, 0, img->height - 1, NULL);
5298	  LineTo (bmpdc, img->width - 1, 0);
5299	}
5300      SelectObject (bmpdc, prev);
5301      DeleteDC (bmpdc);
5302#endif /* HAVE_NTGUI */
5303    }
5304}
5305
5306
5307/* Build a mask for image IMG which is used on frame F.  FILE is the
5308   name of an image file, for error messages.  HOW determines how to
5309   determine the background color of IMG.  If it is a list '(R G B)',
5310   with R, G, and B being integers >= 0, take that as the color of the
5311   background.  Otherwise, determine the background color of IMG
5312   heuristically.  Value is non-zero if successful. */
5313
5314static int
5315x_build_heuristic_mask (f, img, how)
5316     struct frame *f;
5317     struct image *img;
5318     Lisp_Object how;
5319{
5320  XImagePtr_or_DC ximg;
5321#ifndef HAVE_NTGUI
5322  XImagePtr mask_img;
5323#else
5324  HDC frame_dc;
5325  HGDIOBJ prev;
5326  char *mask_img;
5327  int row_width;
5328#endif /* HAVE_NTGUI */
5329  int x, y, rc, use_img_background;
5330  unsigned long bg = 0;
5331
5332  if (img->mask)
5333    {
5334      Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
5335      img->mask = NO_PIXMAP;
5336      img->background_transparent_valid = 0;
5337    }
5338
5339#ifndef HAVE_NTGUI
5340  /* Create an image and pixmap serving as mask.  */
5341  rc = x_create_x_image_and_pixmap (f, img->width, img->height, 1,
5342				    &mask_img, &img->mask);
5343  if (!rc)
5344    return 0;
5345
5346  /* Get the X image of IMG->pixmap.  */
5347  ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap, 0, 0,
5348		    img->width, img->height,
5349		    ~0, ZPixmap);
5350#else
5351  /* Create the bit array serving as mask.  */
5352  row_width = (img->width + 7) / 8;
5353  mask_img = xmalloc (row_width * img->height);
5354  bzero (mask_img, row_width * img->height);
5355
5356  /* Create a memory device context for IMG->pixmap.  */
5357  frame_dc = get_frame_dc (f);
5358  ximg = CreateCompatibleDC (frame_dc);
5359  release_frame_dc (f, frame_dc);
5360  prev = SelectObject (ximg, img->pixmap);
5361#endif /* HAVE_NTGUI */
5362
5363  /* Determine the background color of ximg.  If HOW is `(R G B)'
5364     take that as color.  Otherwise, use the image's background color. */
5365  use_img_background = 1;
5366
5367  if (CONSP (how))
5368    {
5369      int rgb[3], i;
5370
5371      for (i = 0; i < 3 && CONSP (how) && NATNUMP (XCAR (how)); ++i)
5372	{
5373	  rgb[i] = XFASTINT (XCAR (how)) & 0xffff;
5374	  how = XCDR (how);
5375	}
5376
5377      if (i == 3 && NILP (how))
5378	{
5379	  char color_name[30];
5380	  sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]);
5381	  bg = (
5382#ifdef HAVE_NTGUI
5383		0x00ffffff & /* Filter out palette info.  */
5384#endif /* HAVE_NTGUI */
5385		x_alloc_image_color (f, img, build_string (color_name), 0));
5386	  use_img_background = 0;
5387	}
5388    }
5389
5390  if (use_img_background)
5391    bg = four_corners_best (ximg, img->corners, img->width, img->height);
5392
5393  /* Set all bits in mask_img to 1 whose color in ximg is different
5394     from the background color bg.  */
5395#ifndef HAVE_NTGUI
5396  for (y = 0; y < img->height; ++y)
5397    for (x = 0; x < img->width; ++x)
5398      XPutPixel (mask_img, x, y, (XGetPixel (ximg, x, y) != bg
5399				  ? PIX_MASK_DRAW : PIX_MASK_RETAIN));
5400
5401  /* Fill in the background_transparent field while we have the mask handy. */
5402  image_background_transparent (img, f, mask_img);
5403
5404  /* Put mask_img into img->mask.  */
5405  x_put_x_image (f, mask_img, img->mask, img->width, img->height);
5406  x_destroy_x_image (mask_img);
5407
5408#else
5409  for (y = 0; y < img->height; ++y)
5410    for (x = 0; x < img->width; ++x)
5411      {
5412	COLORREF p = GetPixel (ximg, x, y);
5413	if (p != bg)
5414	  mask_img[y * row_width + x / 8] |= 1 << (x % 8);
5415      }
5416
5417  /* Create the mask image.  */
5418  img->mask = w32_create_pixmap_from_bitmap_data (img->width, img->height,
5419						  mask_img);
5420  /* Fill in the background_transparent field while we have the mask handy. */
5421  SelectObject (ximg, img->mask);
5422  image_background_transparent (img, f, ximg);
5423
5424  /* Was: x_destroy_x_image ((XImagePtr )mask_img); which seems bogus ++kfs */
5425  xfree (mask_img);
5426#endif /* HAVE_NTGUI */
5427
5428  Destroy_Image (ximg, prev);
5429
5430  return 1;
5431}
5432
5433
5434/***********************************************************************
5435		       PBM (mono, gray, color)
5436 ***********************************************************************/
5437
5438static int pbm_image_p P_ ((Lisp_Object object));
5439static int pbm_load P_ ((struct frame *f, struct image *img));
5440static int pbm_scan_number P_ ((unsigned char **, unsigned char *));
5441
5442/* The symbol `pbm' identifying images of this type.  */
5443
5444Lisp_Object Qpbm;
5445
5446/* Indices of image specification fields in gs_format, below.  */
5447
5448enum pbm_keyword_index
5449{
5450  PBM_TYPE,
5451  PBM_FILE,
5452  PBM_DATA,
5453  PBM_ASCENT,
5454  PBM_MARGIN,
5455  PBM_RELIEF,
5456  PBM_ALGORITHM,
5457  PBM_HEURISTIC_MASK,
5458  PBM_MASK,
5459  PBM_FOREGROUND,
5460  PBM_BACKGROUND,
5461  PBM_LAST
5462};
5463
5464/* Vector of image_keyword structures describing the format
5465   of valid user-defined image specifications.  */
5466
5467static struct image_keyword pbm_format[PBM_LAST] =
5468{
5469  {":type",		IMAGE_SYMBOL_VALUE,			1},
5470  {":file",		IMAGE_STRING_VALUE,			0},
5471  {":data",		IMAGE_STRING_VALUE,			0},
5472  {":ascent",		IMAGE_ASCENT_VALUE,			0},
5473  {":margin",		IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,	0},
5474  {":relief",		IMAGE_INTEGER_VALUE,			0},
5475  {":conversion",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
5476  {":heuristic-mask",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
5477  {":mask",		IMAGE_DONT_CHECK_VALUE_TYPE,		0},
5478  {":foreground",	IMAGE_STRING_OR_NIL_VALUE,		0},
5479  {":background",	IMAGE_STRING_OR_NIL_VALUE,		0}
5480};
5481
5482/* Structure describing the image type `pbm'.  */
5483
5484static struct image_type pbm_type =
5485{
5486  &Qpbm,
5487  pbm_image_p,
5488  pbm_load,
5489  x_clear_image,
5490  NULL
5491};
5492
5493
5494/* Return non-zero if OBJECT is a valid PBM image specification.  */
5495
5496static int
5497pbm_image_p (object)
5498     Lisp_Object object;
5499{
5500  struct image_keyword fmt[PBM_LAST];
5501
5502  bcopy (pbm_format, fmt, sizeof fmt);
5503
5504  if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm))
5505    return 0;
5506
5507  /* Must specify either :data or :file.  */
5508  return fmt[PBM_DATA].count + fmt[PBM_FILE].count == 1;
5509}
5510
5511
5512/* Scan a decimal number from *S and return it.  Advance *S while
5513   reading the number.  END is the end of the string.  Value is -1 at
5514   end of input.  */
5515
5516static int
5517pbm_scan_number (s, end)
5518     unsigned char **s, *end;
5519{
5520  int c = 0, val = -1;
5521
5522  while (*s < end)
5523    {
5524      /* Skip white-space.  */
5525      while (*s < end && (c = *(*s)++, isspace (c)))
5526	;
5527
5528      if (c == '#')
5529	{
5530	  /* Skip comment to end of line.  */
5531	  while (*s < end && (c = *(*s)++, c != '\n'))
5532	    ;
5533	}
5534      else if (isdigit (c))
5535	{
5536	  /* Read decimal number.  */
5537	  val = c - '0';
5538	  while (*s < end && (c = *(*s)++, isdigit (c)))
5539	    val = 10 * val + c - '0';
5540	  break;
5541	}
5542      else
5543	break;
5544    }
5545
5546  return val;
5547}
5548
5549
5550#ifdef HAVE_NTGUI
5551#if 0  /* Unused. ++kfs  */
5552
5553/* Read FILE into memory.  Value is a pointer to a buffer allocated
5554   with xmalloc holding FILE's contents.  Value is null if an error
5555   occurred.  *SIZE is set to the size of the file.  */
5556
5557static char *
5558pbm_read_file (file, size)
5559     Lisp_Object file;
5560     int *size;
5561{
5562  FILE *fp = NULL;
5563  char *buf = NULL;
5564  struct stat st;
5565
5566  if (stat (SDATA (file), &st) == 0
5567      && (fp = fopen (SDATA (file), "rb")) != NULL
5568      && (buf = (char *) xmalloc (st.st_size),
5569	  fread (buf, 1, st.st_size, fp) == st.st_size))
5570    {
5571      *size = st.st_size;
5572      fclose (fp);
5573    }
5574  else
5575    {
5576      if (fp)
5577	fclose (fp);
5578      if (buf)
5579	{
5580	  xfree (buf);
5581	  buf = NULL;
5582	}
5583    }
5584
5585  return buf;
5586}
5587#endif
5588#endif /* HAVE_NTGUI */
5589
5590/* Load PBM image IMG for use on frame F.  */
5591
5592static int
5593pbm_load (f, img)
5594     struct frame *f;
5595     struct image *img;
5596{
5597  int raw_p, x, y;
5598  int width, height, max_color_idx = 0;
5599  XImagePtr ximg;
5600  Lisp_Object file, specified_file;
5601  enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
5602  struct gcpro gcpro1;
5603  unsigned char *contents = NULL;
5604  unsigned char *end, *p;
5605  int size;
5606
5607  specified_file = image_spec_value (img->spec, QCfile, NULL);
5608  file = Qnil;
5609  GCPRO1 (file);
5610
5611  if (STRINGP (specified_file))
5612    {
5613      file = x_find_image_file (specified_file);
5614      if (!STRINGP (file))
5615	{
5616	  image_error ("Cannot find image file `%s'", specified_file, Qnil);
5617	  UNGCPRO;
5618	  return 0;
5619	}
5620
5621      contents = slurp_file (SDATA (file), &size);
5622      if (contents == NULL)
5623	{
5624	  image_error ("Error reading `%s'", file, Qnil);
5625	  UNGCPRO;
5626	  return 0;
5627	}
5628
5629      p = contents;
5630      end = contents + size;
5631    }
5632  else
5633    {
5634      Lisp_Object data;
5635      data = image_spec_value (img->spec, QCdata, NULL);
5636      p = SDATA (data);
5637      end = p + SBYTES (data);
5638    }
5639
5640  /* Check magic number.  */
5641  if (end - p < 2 || *p++ != 'P')
5642    {
5643      image_error ("Not a PBM image: `%s'", img->spec, Qnil);
5644    error:
5645      xfree (contents);
5646      UNGCPRO;
5647      return 0;
5648    }
5649
5650  switch (*p++)
5651    {
5652    case '1':
5653      raw_p = 0, type = PBM_MONO;
5654      break;
5655
5656    case '2':
5657      raw_p = 0, type = PBM_GRAY;
5658      break;
5659
5660    case '3':
5661      raw_p = 0, type = PBM_COLOR;
5662      break;
5663
5664    case '4':
5665      raw_p = 1, type = PBM_MONO;
5666      break;
5667
5668    case '5':
5669      raw_p = 1, type = PBM_GRAY;
5670      break;
5671
5672    case '6':
5673      raw_p = 1, type = PBM_COLOR;
5674      break;
5675
5676    default:
5677      image_error ("Not a PBM image: `%s'", img->spec, Qnil);
5678      goto error;
5679    }
5680
5681  /* Read width, height, maximum color-component.  Characters
5682     starting with `#' up to the end of a line are ignored.  */
5683  width = pbm_scan_number (&p, end);
5684  height = pbm_scan_number (&p, end);
5685
5686  if (type != PBM_MONO)
5687    {
5688      max_color_idx = pbm_scan_number (&p, end);
5689      if (raw_p && max_color_idx > 255)
5690	max_color_idx = 255;
5691    }
5692
5693  if (!check_image_size (f, width, height)
5694      || (type != PBM_MONO && max_color_idx < 0))
5695    goto error;
5696
5697  if (!x_create_x_image_and_pixmap (f, width, height, 0,
5698				    &ximg, &img->pixmap))
5699    goto error;
5700
5701  /* Initialize the color hash table.  */
5702  init_color_table ();
5703
5704  if (type == PBM_MONO)
5705    {
5706      int c = 0, g;
5707      struct image_keyword fmt[PBM_LAST];
5708      unsigned long fg = FRAME_FOREGROUND_PIXEL (f);
5709      unsigned long bg = FRAME_BACKGROUND_PIXEL (f);
5710
5711      /* Parse the image specification.  */
5712      bcopy (pbm_format, fmt, sizeof fmt);
5713      parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm);
5714
5715      /* Get foreground and background colors, maybe allocate colors.  */
5716      if (fmt[PBM_FOREGROUND].count
5717	  && STRINGP (fmt[PBM_FOREGROUND].value))
5718	fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg);
5719      if (fmt[PBM_BACKGROUND].count
5720	  && STRINGP (fmt[PBM_BACKGROUND].value))
5721	{
5722	  bg = x_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg);
5723	  img->background = bg;
5724	  img->background_valid = 1;
5725	}
5726
5727      for (y = 0; y < height; ++y)
5728	for (x = 0; x < width; ++x)
5729	  {
5730	    if (raw_p)
5731	      {
5732		if ((x & 7) == 0)
5733		  c = *p++;
5734		g = c & 0x80;
5735		c <<= 1;
5736	      }
5737	    else
5738	      g = pbm_scan_number (&p, end);
5739
5740	    XPutPixel (ximg, x, y, g ? fg : bg);
5741	  }
5742    }
5743  else
5744    {
5745      if (raw_p
5746	  && ((type == PBM_GRAY)
5747	      ? (p + height * width > end)
5748	      : (p + 3 * height * width > end)))
5749	{
5750	  x_destroy_x_image (ximg);
5751	  x_clear_image (f, img);
5752	  image_error ("Invalid image size in image `%s'",
5753		       img->spec, Qnil);
5754	  goto error;
5755	}
5756
5757      for (y = 0; y < height; ++y)
5758	for (x = 0; x < width; ++x)
5759	  {
5760	    int r, g, b;
5761
5762	    if (type == PBM_GRAY)
5763	      r = g = b = raw_p ? *p++ : pbm_scan_number (&p, end);
5764	    else if (raw_p)
5765	      {
5766		r = *p++;
5767		g = *p++;
5768		b = *p++;
5769	      }
5770	    else
5771	      {
5772		r = pbm_scan_number (&p, end);
5773		g = pbm_scan_number (&p, end);
5774		b = pbm_scan_number (&p, end);
5775	      }
5776
5777	    if (r < 0 || g < 0 || b < 0)
5778	      {
5779		x_destroy_x_image (ximg);
5780		image_error ("Invalid pixel value in image `%s'",
5781			     img->spec, Qnil);
5782		goto error;
5783	      }
5784
5785	    /* RGB values are now in the range 0..max_color_idx.
5786	       Scale this to the range 0..0xffff supported by X.  */
5787	    r = (double) r * 65535 / max_color_idx;
5788	    g = (double) g * 65535 / max_color_idx;
5789	    b = (double) b * 65535 / max_color_idx;
5790	    XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
5791	  }
5792    }
5793
5794#ifdef COLOR_TABLE_SUPPORT
5795  /* Store in IMG->colors the colors allocated for the image, and
5796     free the color table.  */
5797  img->colors = colors_in_color_table (&img->ncolors);
5798  free_color_table ();
5799#endif /* COLOR_TABLE_SUPPORT */
5800
5801  img->width = width;
5802  img->height = height;
5803
5804  /* Maybe fill in the background field while we have ximg handy.  */
5805
5806  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
5807    /* Casting avoids a GCC warning.  */
5808    IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
5809
5810  /* Put the image into a pixmap.  */
5811  x_put_x_image (f, ximg, img->pixmap, width, height);
5812  x_destroy_x_image (ximg);
5813
5814  /* X and W32 versions did it here, MAC version above.  ++kfs
5815     img->width = width;
5816     img->height = height; */
5817
5818  UNGCPRO;
5819  xfree (contents);
5820  return 1;
5821}
5822
5823
5824/***********************************************************************
5825				 PNG
5826 ***********************************************************************/
5827
5828#if defined (HAVE_PNG) || defined (MAC_OS)
5829
5830/* Function prototypes.  */
5831
5832static int png_image_p P_ ((Lisp_Object object));
5833static int png_load P_ ((struct frame *f, struct image *img));
5834
5835/* The symbol `png' identifying images of this type.  */
5836
5837Lisp_Object Qpng;
5838
5839/* Indices of image specification fields in png_format, below.  */
5840
5841enum png_keyword_index
5842{
5843  PNG_TYPE,
5844  PNG_DATA,
5845  PNG_FILE,
5846  PNG_ASCENT,
5847  PNG_MARGIN,
5848  PNG_RELIEF,
5849  PNG_ALGORITHM,
5850  PNG_HEURISTIC_MASK,
5851  PNG_MASK,
5852  PNG_BACKGROUND,
5853  PNG_LAST
5854};
5855
5856/* Vector of image_keyword structures describing the format
5857   of valid user-defined image specifications.  */
5858
5859static struct image_keyword png_format[PNG_LAST] =
5860{
5861  {":type",		IMAGE_SYMBOL_VALUE,			1},
5862  {":data",		IMAGE_STRING_VALUE,			0},
5863  {":file",		IMAGE_STRING_VALUE,			0},
5864  {":ascent",		IMAGE_ASCENT_VALUE,			0},
5865  {":margin",		IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,	0},
5866  {":relief",		IMAGE_INTEGER_VALUE,			0},
5867  {":conversion",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
5868  {":heuristic-mask",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
5869  {":mask",		IMAGE_DONT_CHECK_VALUE_TYPE,		0},
5870  {":background",	IMAGE_STRING_OR_NIL_VALUE,		0}
5871};
5872
5873/* Structure describing the image type `png'.  */
5874
5875static struct image_type png_type =
5876{
5877  &Qpng,
5878  png_image_p,
5879  png_load,
5880  x_clear_image,
5881  NULL
5882};
5883
5884/* Return non-zero if OBJECT is a valid PNG image specification.  */
5885
5886static int
5887png_image_p (object)
5888     Lisp_Object object;
5889{
5890  struct image_keyword fmt[PNG_LAST];
5891  bcopy (png_format, fmt, sizeof fmt);
5892
5893  if (!parse_image_spec (object, fmt, PNG_LAST, Qpng))
5894    return 0;
5895
5896  /* Must specify either the :data or :file keyword.  */
5897  return fmt[PNG_FILE].count + fmt[PNG_DATA].count == 1;
5898}
5899
5900#endif /* HAVE_PNG || MAC_OS */
5901
5902
5903#ifdef HAVE_PNG
5904
5905#if defined HAVE_LIBPNG_PNG_H
5906# include <libpng/png.h>
5907#else
5908# include <png.h>
5909#endif
5910
5911#ifdef HAVE_NTGUI
5912/* PNG library details.  */
5913
5914DEF_IMGLIB_FN (png_get_io_ptr);
5915DEF_IMGLIB_FN (png_check_sig);
5916DEF_IMGLIB_FN (png_create_read_struct);
5917DEF_IMGLIB_FN (png_create_info_struct);
5918DEF_IMGLIB_FN (png_destroy_read_struct);
5919DEF_IMGLIB_FN (png_set_read_fn);
5920DEF_IMGLIB_FN (png_set_sig_bytes);
5921DEF_IMGLIB_FN (png_read_info);
5922DEF_IMGLIB_FN (png_get_IHDR);
5923DEF_IMGLIB_FN (png_get_valid);
5924DEF_IMGLIB_FN (png_set_strip_16);
5925DEF_IMGLIB_FN (png_set_expand);
5926DEF_IMGLIB_FN (png_set_gray_to_rgb);
5927DEF_IMGLIB_FN (png_set_background);
5928DEF_IMGLIB_FN (png_get_bKGD);
5929DEF_IMGLIB_FN (png_read_update_info);
5930DEF_IMGLIB_FN (png_get_channels);
5931DEF_IMGLIB_FN (png_get_rowbytes);
5932DEF_IMGLIB_FN (png_read_image);
5933DEF_IMGLIB_FN (png_read_end);
5934DEF_IMGLIB_FN (png_error);
5935
5936static int
5937init_png_functions (Lisp_Object libraries)
5938{
5939  HMODULE library;
5940
5941  /* Try loading libpng under probable names.  */
5942  if (!(library = w32_delayed_load (libraries, Qpng)))
5943    return 0;
5944
5945  LOAD_IMGLIB_FN (library, png_get_io_ptr);
5946  LOAD_IMGLIB_FN (library, png_check_sig);
5947  LOAD_IMGLIB_FN (library, png_create_read_struct);
5948  LOAD_IMGLIB_FN (library, png_create_info_struct);
5949  LOAD_IMGLIB_FN (library, png_destroy_read_struct);
5950  LOAD_IMGLIB_FN (library, png_set_read_fn);
5951  LOAD_IMGLIB_FN (library, png_set_sig_bytes);
5952  LOAD_IMGLIB_FN (library, png_read_info);
5953  LOAD_IMGLIB_FN (library, png_get_IHDR);
5954  LOAD_IMGLIB_FN (library, png_get_valid);
5955  LOAD_IMGLIB_FN (library, png_set_strip_16);
5956  LOAD_IMGLIB_FN (library, png_set_expand);
5957  LOAD_IMGLIB_FN (library, png_set_gray_to_rgb);
5958  LOAD_IMGLIB_FN (library, png_set_background);
5959  LOAD_IMGLIB_FN (library, png_get_bKGD);
5960  LOAD_IMGLIB_FN (library, png_read_update_info);
5961  LOAD_IMGLIB_FN (library, png_get_channels);
5962  LOAD_IMGLIB_FN (library, png_get_rowbytes);
5963  LOAD_IMGLIB_FN (library, png_read_image);
5964  LOAD_IMGLIB_FN (library, png_read_end);
5965  LOAD_IMGLIB_FN (library, png_error);
5966  return 1;
5967}
5968#else
5969
5970#define fn_png_get_io_ptr		png_get_io_ptr
5971#define fn_png_check_sig		png_check_sig
5972#define fn_png_create_read_struct	png_create_read_struct
5973#define fn_png_create_info_struct	png_create_info_struct
5974#define fn_png_destroy_read_struct	png_destroy_read_struct
5975#define fn_png_set_read_fn		png_set_read_fn
5976#define fn_png_set_sig_bytes		png_set_sig_bytes
5977#define fn_png_read_info		png_read_info
5978#define fn_png_get_IHDR			png_get_IHDR
5979#define fn_png_get_valid		png_get_valid
5980#define fn_png_set_strip_16		png_set_strip_16
5981#define fn_png_set_expand		png_set_expand
5982#define fn_png_set_gray_to_rgb		png_set_gray_to_rgb
5983#define fn_png_set_background		png_set_background
5984#define fn_png_get_bKGD			png_get_bKGD
5985#define fn_png_read_update_info		png_read_update_info
5986#define fn_png_get_channels		png_get_channels
5987#define fn_png_get_rowbytes		png_get_rowbytes
5988#define fn_png_read_image		png_read_image
5989#define fn_png_read_end			png_read_end
5990#define fn_png_error			png_error
5991
5992#endif /* HAVE_NTGUI */
5993
5994/* Error and warning handlers installed when the PNG library
5995   is initialized.  */
5996
5997static void
5998my_png_error (png_ptr, msg)
5999     png_struct *png_ptr;
6000     char *msg;
6001{
6002  xassert (png_ptr != NULL);
6003  image_error ("PNG error: %s", build_string (msg), Qnil);
6004  longjmp (png_ptr->jmpbuf, 1);
6005}
6006
6007
6008static void
6009my_png_warning (png_ptr, msg)
6010     png_struct *png_ptr;
6011     char *msg;
6012{
6013  xassert (png_ptr != NULL);
6014  image_error ("PNG warning: %s", build_string (msg), Qnil);
6015}
6016
6017/* Memory source for PNG decoding.  */
6018
6019struct png_memory_storage
6020{
6021  unsigned char *bytes;		/* The data       */
6022  size_t len;			/* How big is it? */
6023  int index;			/* Where are we?  */
6024};
6025
6026
6027/* Function set as reader function when reading PNG image from memory.
6028   PNG_PTR is a pointer to the PNG control structure.  Copy LENGTH
6029   bytes from the input to DATA.  */
6030
6031static void
6032png_read_from_memory (png_ptr, data, length)
6033     png_structp png_ptr;
6034     png_bytep data;
6035     png_size_t length;
6036{
6037  struct png_memory_storage *tbr
6038    = (struct png_memory_storage *) fn_png_get_io_ptr (png_ptr);
6039
6040  if (length > tbr->len - tbr->index)
6041    fn_png_error (png_ptr, "Read error");
6042
6043  bcopy (tbr->bytes + tbr->index, data, length);
6044  tbr->index = tbr->index + length;
6045}
6046
6047
6048/* Function set as reader function when reading PNG image from a file.
6049   PNG_PTR is a pointer to the PNG control structure.  Copy LENGTH
6050   bytes from the input to DATA.  */
6051
6052static void
6053png_read_from_file (png_ptr, data, length)
6054     png_structp png_ptr;
6055     png_bytep data;
6056     png_size_t length;
6057{
6058  FILE *fp = (FILE *) fn_png_get_io_ptr (png_ptr);
6059
6060  if (fread (data, 1, length, fp) < length)
6061    fn_png_error (png_ptr, "Read error");
6062}
6063
6064
6065/* Load PNG image IMG for use on frame F.  Value is non-zero if
6066   successful.  */
6067
6068static int
6069png_load (f, img)
6070     struct frame *f;
6071     struct image *img;
6072{
6073  Lisp_Object file, specified_file;
6074  Lisp_Object specified_data;
6075  int x, y, i;
6076  XImagePtr ximg, mask_img = NULL;
6077  struct gcpro gcpro1;
6078  png_struct *png_ptr = NULL;
6079  png_info *info_ptr = NULL, *end_info = NULL;
6080  FILE *volatile fp = NULL;
6081  png_byte sig[8];
6082  png_byte * volatile pixels = NULL;
6083  png_byte ** volatile rows = NULL;
6084  png_uint_32 width, height;
6085  int bit_depth, color_type, interlace_type;
6086  png_byte channels;
6087  png_uint_32 row_bytes;
6088  int transparent_p;
6089  double screen_gamma;
6090  struct png_memory_storage tbr;  /* Data to be read */
6091
6092  /* Find out what file to load.  */
6093  specified_file = image_spec_value (img->spec, QCfile, NULL);
6094  specified_data = image_spec_value (img->spec, QCdata, NULL);
6095  file = Qnil;
6096  GCPRO1 (file);
6097
6098  if (NILP (specified_data))
6099    {
6100      file = x_find_image_file (specified_file);
6101      if (!STRINGP (file))
6102	{
6103	  image_error ("Cannot find image file `%s'", specified_file, Qnil);
6104	  UNGCPRO;
6105	  return 0;
6106	}
6107
6108      /* Open the image file.  */
6109      fp = fopen (SDATA (file), "rb");
6110      if (!fp)
6111	{
6112	  image_error ("Cannot open image file `%s'", file, Qnil);
6113	  UNGCPRO;
6114	  return 0;
6115	}
6116
6117      /* Check PNG signature.  */
6118      if (fread (sig, 1, sizeof sig, fp) != sizeof sig
6119	  || !fn_png_check_sig (sig, sizeof sig))
6120	{
6121	  image_error ("Not a PNG file: `%s'", file, Qnil);
6122	  UNGCPRO;
6123	  fclose (fp);
6124	  return 0;
6125	}
6126    }
6127  else
6128    {
6129      /* Read from memory.  */
6130      tbr.bytes = SDATA (specified_data);
6131      tbr.len = SBYTES (specified_data);
6132      tbr.index = 0;
6133
6134      /* Check PNG signature.  */
6135      if (tbr.len < sizeof sig
6136	  || !fn_png_check_sig (tbr.bytes, sizeof sig))
6137	{
6138	  image_error ("Not a PNG image: `%s'", img->spec, Qnil);
6139	  UNGCPRO;
6140	  return 0;
6141	}
6142
6143      /* Need to skip past the signature.  */
6144      tbr.bytes += sizeof (sig);
6145    }
6146
6147  /* Initialize read and info structs for PNG lib.  Casting return
6148     value avoids a GCC warning on W32.  */
6149  png_ptr = (png_structp)fn_png_create_read_struct (PNG_LIBPNG_VER_STRING,
6150						    NULL, my_png_error,
6151						    my_png_warning);
6152  if (!png_ptr)
6153    {
6154      if (fp) fclose (fp);
6155      UNGCPRO;
6156      return 0;
6157    }
6158
6159  /* Casting return value avoids a GCC warning on W32.  */
6160  info_ptr = (png_infop)fn_png_create_info_struct (png_ptr);
6161  if (!info_ptr)
6162    {
6163      fn_png_destroy_read_struct (&png_ptr, NULL, NULL);
6164      if (fp) fclose (fp);
6165      UNGCPRO;
6166      return 0;
6167    }
6168
6169  /* Casting return value avoids a GCC warning on W32.  */
6170  end_info = (png_infop)fn_png_create_info_struct (png_ptr);
6171  if (!end_info)
6172    {
6173      fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
6174      if (fp) fclose (fp);
6175      UNGCPRO;
6176      return 0;
6177    }
6178
6179  /* Set error jump-back.  We come back here when the PNG library
6180     detects an error.  */
6181  if (setjmp (png_ptr->jmpbuf))
6182    {
6183    error:
6184      if (png_ptr)
6185        fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
6186      xfree (pixels);
6187      xfree (rows);
6188      if (fp) fclose (fp);
6189      UNGCPRO;
6190      return 0;
6191    }
6192
6193  /* Read image info.  */
6194  if (!NILP (specified_data))
6195    fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory);
6196  else
6197    fn_png_set_read_fn (png_ptr, (void *) fp, png_read_from_file);
6198
6199  fn_png_set_sig_bytes (png_ptr, sizeof sig);
6200  fn_png_read_info (png_ptr, info_ptr);
6201  fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
6202		   &interlace_type, NULL, NULL);
6203
6204  if (!check_image_size (f, width, height))
6205    goto error;
6206
6207  /* If image contains simply transparency data, we prefer to
6208     construct a clipping mask.  */
6209  if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
6210    transparent_p = 1;
6211  else
6212    transparent_p = 0;
6213
6214  /* This function is easier to write if we only have to handle
6215     one data format: RGB or RGBA with 8 bits per channel.  Let's
6216     transform other formats into that format.  */
6217
6218  /* Strip more than 8 bits per channel.  */
6219  if (bit_depth == 16)
6220    fn_png_set_strip_16 (png_ptr);
6221
6222  /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
6223     if available.  */
6224  fn_png_set_expand (png_ptr);
6225
6226  /* Convert grayscale images to RGB.  */
6227  if (color_type == PNG_COLOR_TYPE_GRAY
6228      || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
6229    fn_png_set_gray_to_rgb (png_ptr);
6230
6231  screen_gamma = (f->gamma ? 1 / f->gamma / 0.45455 : 2.2);
6232
6233#if 0 /* Avoid double gamma correction for PNG images. */
6234  { /* Tell the PNG lib to handle gamma correction for us.  */
6235    int intent;
6236    double image_gamma;
6237#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
6238    if (png_get_sRGB (png_ptr, info_ptr, &intent))
6239      /* The libpng documentation says this is right in this case.  */
6240      png_set_gamma (png_ptr, screen_gamma, 0.45455);
6241    else
6242#endif
6243      if (png_get_gAMA (png_ptr, info_ptr, &image_gamma))
6244	/* Image contains gamma information.  */
6245	png_set_gamma (png_ptr, screen_gamma, image_gamma);
6246      else
6247	/* Use the standard default for the image gamma.  */
6248	png_set_gamma (png_ptr, screen_gamma, 0.45455);
6249  }
6250#endif /* if 0 */
6251
6252  /* Handle alpha channel by combining the image with a background
6253     color.  Do this only if a real alpha channel is supplied.  For
6254     simple transparency, we prefer a clipping mask.  */
6255  if (!transparent_p)
6256    {
6257      png_color_16 *image_bg;
6258      Lisp_Object specified_bg
6259	= image_spec_value (img->spec, QCbackground, NULL);
6260
6261      if (STRINGP (specified_bg))
6262	/* The user specified `:background', use that.  */
6263	{
6264	  /* W32 version incorrectly used COLORREF here!!  ++kfs */
6265	  XColor color;
6266	  if (x_defined_color (f, SDATA (specified_bg), &color, 0))
6267	    {
6268	      png_color_16 user_bg;
6269
6270	      bzero (&user_bg, sizeof user_bg);
6271	      user_bg.red = color.red >> 8;
6272	      user_bg.green = color.green >> 8;
6273	      user_bg.blue = color.blue >> 8;
6274
6275	      fn_png_set_background (png_ptr, &user_bg,
6276				     PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
6277	    }
6278	}
6279      else if (fn_png_get_bKGD (png_ptr, info_ptr, &image_bg))
6280	/* Image contains a background color with which to
6281	   combine the image.  */
6282	fn_png_set_background (png_ptr, image_bg,
6283			       PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
6284      else
6285	{
6286	  /* Image does not contain a background color with which
6287	     to combine the image data via an alpha channel.  Use
6288	     the frame's background instead.  */
6289#ifdef HAVE_X_WINDOWS
6290	  XColor color;
6291	  png_color_16 frame_background;
6292
6293	  color.pixel = FRAME_BACKGROUND_PIXEL (f);
6294	  x_query_color (f, &color);
6295
6296	  bzero (&frame_background, sizeof frame_background);
6297	  frame_background.red = color.red >> 8;
6298	  frame_background.green = color.green >> 8;
6299	  frame_background.blue = color.blue >> 8;
6300#endif /* HAVE_X_WINDOWS */
6301
6302#ifdef HAVE_NTGUI
6303	  COLORREF color;
6304	  png_color_16 frame_background;
6305	  color = FRAME_BACKGROUND_PIXEL (f);
6306#if 0 /* W32 TODO : Colormap support.  */
6307	  x_query_color (f, &color);
6308#endif
6309	  bzero (&frame_background, sizeof frame_background);
6310	  frame_background.red = GetRValue (color);
6311	  frame_background.green = GetGValue (color);
6312	  frame_background.blue = GetBValue (color);
6313#endif /* HAVE_NTGUI */
6314
6315#ifdef MAC_OS
6316	  unsigned long color;
6317	  png_color_16 frame_background;
6318	  color = FRAME_BACKGROUND_PIXEL (f);
6319#if 0 /* MAC/W32 TODO : Colormap support.  */
6320	  x_query_color (f, &color);
6321#endif
6322	  bzero (&frame_background, sizeof frame_background);
6323	  frame_background.red = RED_FROM_ULONG (color);
6324	  frame_background.green = GREEN_FROM_ULONG (color);
6325	  frame_background.blue = BLUE_FROM_ULONG (color);
6326#endif /* MAC_OS */
6327
6328	  fn_png_set_background (png_ptr, &frame_background,
6329				 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
6330	}
6331    }
6332
6333  /* Update info structure.  */
6334  fn_png_read_update_info (png_ptr, info_ptr);
6335
6336  /* Get number of channels.  Valid values are 1 for grayscale images
6337     and images with a palette, 2 for grayscale images with transparency
6338     information (alpha channel), 3 for RGB images, and 4 for RGB
6339     images with alpha channel, i.e. RGBA.  If conversions above were
6340     sufficient we should only have 3 or 4 channels here.  */
6341  channels = fn_png_get_channels (png_ptr, info_ptr);
6342  xassert (channels == 3 || channels == 4);
6343
6344  /* Number of bytes needed for one row of the image.  */
6345  row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr);
6346
6347  /* Allocate memory for the image.  */
6348  pixels = (png_byte *) xmalloc (row_bytes * height * sizeof *pixels);
6349  rows = (png_byte **) xmalloc (height * sizeof *rows);
6350  for (i = 0; i < height; ++i)
6351    rows[i] = pixels + i * row_bytes;
6352
6353  /* Read the entire image.  */
6354  fn_png_read_image (png_ptr, rows);
6355  fn_png_read_end (png_ptr, info_ptr);
6356  if (fp)
6357    {
6358      fclose (fp);
6359      fp = NULL;
6360    }
6361
6362  /* Create the X image and pixmap.  */
6363  if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,
6364				    &img->pixmap))
6365    goto error;
6366
6367  /* Create an image and pixmap serving as mask if the PNG image
6368     contains an alpha channel.  */
6369  if (channels == 4
6370      && !transparent_p
6371      && !x_create_x_image_and_pixmap (f, width, height, 1,
6372				       &mask_img, &img->mask))
6373    {
6374      x_destroy_x_image (ximg);
6375      Free_Pixmap (FRAME_X_DISPLAY (f), img->pixmap);
6376      img->pixmap = NO_PIXMAP;
6377      goto error;
6378    }
6379
6380  /* Fill the X image and mask from PNG data.  */
6381  init_color_table ();
6382
6383  for (y = 0; y < height; ++y)
6384    {
6385      png_byte *p = rows[y];
6386
6387      for (x = 0; x < width; ++x)
6388	{
6389	  unsigned r, g, b;
6390
6391	  r = *p++ << 8;
6392	  g = *p++ << 8;
6393	  b = *p++ << 8;
6394	  XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
6395	  /* An alpha channel, aka mask channel, associates variable
6396	     transparency with an image.  Where other image formats
6397	     support binary transparency---fully transparent or fully
6398	     opaque---PNG allows up to 254 levels of partial transparency.
6399	     The PNG library implements partial transparency by combining
6400	     the image with a specified background color.
6401
6402	     I'm not sure how to handle this here nicely: because the
6403	     background on which the image is displayed may change, for
6404	     real alpha channel support, it would be necessary to create
6405	     a new image for each possible background.
6406
6407	     What I'm doing now is that a mask is created if we have
6408	     boolean transparency information.  Otherwise I'm using
6409	     the frame's background color to combine the image with.  */
6410
6411	  if (channels == 4)
6412	    {
6413	      if (mask_img)
6414		XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN);
6415	      ++p;
6416	    }
6417	}
6418    }
6419
6420  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
6421    /* Set IMG's background color from the PNG image, unless the user
6422       overrode it.  */
6423    {
6424      png_color_16 *bg;
6425      if (fn_png_get_bKGD (png_ptr, info_ptr, &bg))
6426	{
6427	  img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue);
6428	  img->background_valid = 1;
6429	}
6430    }
6431
6432#ifdef COLOR_TABLE_SUPPORT
6433  /* Remember colors allocated for this image.  */
6434  img->colors = colors_in_color_table (&img->ncolors);
6435  free_color_table ();
6436#endif /* COLOR_TABLE_SUPPORT */
6437
6438  /* Clean up.  */
6439  fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
6440  xfree (rows);
6441  xfree (pixels);
6442
6443  img->width = width;
6444  img->height = height;
6445
6446  /* Maybe fill in the background field while we have ximg handy.
6447     Casting avoids a GCC warning.  */
6448  IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
6449
6450  /* Put the image into the pixmap, then free the X image and its buffer.  */
6451  x_put_x_image (f, ximg, img->pixmap, width, height);
6452  x_destroy_x_image (ximg);
6453
6454  /* Same for the mask.  */
6455  if (mask_img)
6456    {
6457      /* Fill in the background_transparent field while we have the
6458	 mask handy.  Casting avoids a GCC warning.  */
6459      image_background_transparent (img, f, (XImagePtr_or_DC)mask_img);
6460
6461      x_put_x_image (f, mask_img, img->mask, img->width, img->height);
6462      x_destroy_x_image (mask_img);
6463    }
6464
6465  UNGCPRO;
6466  return 1;
6467}
6468
6469#else /* HAVE_PNG */
6470
6471#ifdef MAC_OS
6472static int
6473png_load (f, img)
6474     struct frame *f;
6475     struct image *img;
6476{
6477#ifdef MAC_OSX
6478  if (MyCGImageCreateWithPNGDataProvider)
6479    return image_load_quartz2d (f, img, 1);
6480  else
6481#endif
6482    return image_load_quicktime (f, img, kQTFileTypePNG);
6483}
6484#endif  /* MAC_OS */
6485
6486#endif /* !HAVE_PNG */
6487
6488
6489
6490/***********************************************************************
6491				 JPEG
6492 ***********************************************************************/
6493
6494#if defined (HAVE_JPEG) || defined (MAC_OS)
6495
6496static int jpeg_image_p P_ ((Lisp_Object object));
6497static int jpeg_load P_ ((struct frame *f, struct image *img));
6498
6499/* The symbol `jpeg' identifying images of this type.  */
6500
6501Lisp_Object Qjpeg;
6502
6503/* Indices of image specification fields in gs_format, below.  */
6504
6505enum jpeg_keyword_index
6506{
6507  JPEG_TYPE,
6508  JPEG_DATA,
6509  JPEG_FILE,
6510  JPEG_ASCENT,
6511  JPEG_MARGIN,
6512  JPEG_RELIEF,
6513  JPEG_ALGORITHM,
6514  JPEG_HEURISTIC_MASK,
6515  JPEG_MASK,
6516  JPEG_BACKGROUND,
6517  JPEG_LAST
6518};
6519
6520/* Vector of image_keyword structures describing the format
6521   of valid user-defined image specifications.  */
6522
6523static struct image_keyword jpeg_format[JPEG_LAST] =
6524{
6525  {":type",		IMAGE_SYMBOL_VALUE,			1},
6526  {":data",		IMAGE_STRING_VALUE,			0},
6527  {":file",		IMAGE_STRING_VALUE,			0},
6528  {":ascent",		IMAGE_ASCENT_VALUE,			0},
6529  {":margin",		IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,	0},
6530  {":relief",		IMAGE_INTEGER_VALUE,			0},
6531  {":conversions",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
6532  {":heuristic-mask",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
6533  {":mask",		IMAGE_DONT_CHECK_VALUE_TYPE,		0},
6534  {":background",	IMAGE_STRING_OR_NIL_VALUE,		0}
6535};
6536
6537/* Structure describing the image type `jpeg'.  */
6538
6539static struct image_type jpeg_type =
6540{
6541  &Qjpeg,
6542  jpeg_image_p,
6543  jpeg_load,
6544  x_clear_image,
6545  NULL
6546};
6547
6548/* Return non-zero if OBJECT is a valid JPEG image specification.  */
6549
6550static int
6551jpeg_image_p (object)
6552     Lisp_Object object;
6553{
6554  struct image_keyword fmt[JPEG_LAST];
6555
6556  bcopy (jpeg_format, fmt, sizeof fmt);
6557
6558  if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg))
6559    return 0;
6560
6561  /* Must specify either the :data or :file keyword.  */
6562  return fmt[JPEG_FILE].count + fmt[JPEG_DATA].count == 1;
6563}
6564
6565#endif /* HAVE_JPEG || MAC_OS */
6566
6567#ifdef HAVE_JPEG
6568
6569/* Work around a warning about HAVE_STDLIB_H being redefined in
6570   jconfig.h.  */
6571#ifdef HAVE_STDLIB_H
6572#define HAVE_STDLIB_H_1
6573#undef HAVE_STDLIB_H
6574#endif /* HAVE_STLIB_H */
6575
6576#if defined (HAVE_NTGUI) && !defined (__WIN32__)
6577/* In older releases of the jpeg library, jpeglib.h will define boolean
6578   differently depending on __WIN32__, so make sure it is defined.  */
6579#define __WIN32__ 1
6580#endif
6581
6582#include <jpeglib.h>
6583#include <jerror.h>
6584#include <setjmp.h>
6585
6586#ifdef HAVE_STLIB_H_1
6587#define HAVE_STDLIB_H 1
6588#endif
6589
6590#ifdef HAVE_NTGUI
6591
6592/* JPEG library details.  */
6593DEF_IMGLIB_FN (jpeg_CreateDecompress);
6594DEF_IMGLIB_FN (jpeg_start_decompress);
6595DEF_IMGLIB_FN (jpeg_finish_decompress);
6596DEF_IMGLIB_FN (jpeg_destroy_decompress);
6597DEF_IMGLIB_FN (jpeg_read_header);
6598DEF_IMGLIB_FN (jpeg_read_scanlines);
6599DEF_IMGLIB_FN (jpeg_std_error);
6600DEF_IMGLIB_FN (jpeg_resync_to_restart);
6601
6602static int
6603init_jpeg_functions (Lisp_Object libraries)
6604{
6605  HMODULE library;
6606
6607  if (!(library = w32_delayed_load (libraries, Qjpeg)))
6608    return 0;
6609
6610  LOAD_IMGLIB_FN (library, jpeg_finish_decompress);
6611  LOAD_IMGLIB_FN (library, jpeg_read_scanlines);
6612  LOAD_IMGLIB_FN (library, jpeg_start_decompress);
6613  LOAD_IMGLIB_FN (library, jpeg_read_header);
6614  LOAD_IMGLIB_FN (library, jpeg_CreateDecompress);
6615  LOAD_IMGLIB_FN (library, jpeg_destroy_decompress);
6616  LOAD_IMGLIB_FN (library, jpeg_std_error);
6617  LOAD_IMGLIB_FN (library, jpeg_resync_to_restart);
6618  return 1;
6619}
6620
6621/* Wrapper since we can't directly assign the function pointer
6622   to another function pointer that was declared more completely easily.  */
6623static boolean
6624jpeg_resync_to_restart_wrapper(cinfo, desired)
6625     j_decompress_ptr cinfo;
6626     int desired;
6627{
6628  return fn_jpeg_resync_to_restart (cinfo, desired);
6629}
6630
6631#else
6632
6633#define fn_jpeg_CreateDecompress(a,b,c)	jpeg_create_decompress(a)
6634#define fn_jpeg_start_decompress	jpeg_start_decompress
6635#define fn_jpeg_finish_decompress	jpeg_finish_decompress
6636#define fn_jpeg_destroy_decompress	jpeg_destroy_decompress
6637#define fn_jpeg_read_header		jpeg_read_header
6638#define fn_jpeg_read_scanlines		jpeg_read_scanlines
6639#define fn_jpeg_std_error		jpeg_std_error
6640#define jpeg_resync_to_restart_wrapper	jpeg_resync_to_restart
6641
6642#endif /* HAVE_NTGUI */
6643
6644struct my_jpeg_error_mgr
6645{
6646  struct jpeg_error_mgr pub;
6647  jmp_buf setjmp_buffer;
6648};
6649
6650
6651static void
6652my_error_exit (cinfo)
6653     j_common_ptr cinfo;
6654{
6655  struct my_jpeg_error_mgr *mgr = (struct my_jpeg_error_mgr *) cinfo->err;
6656  longjmp (mgr->setjmp_buffer, 1);
6657}
6658
6659
6660/* Init source method for JPEG data source manager.  Called by
6661   jpeg_read_header() before any data is actually read.  See
6662   libjpeg.doc from the JPEG lib distribution.  */
6663
6664static void
6665our_common_init_source (cinfo)
6666     j_decompress_ptr cinfo;
6667{
6668}
6669
6670
6671/* Method to terminate data source.  Called by
6672   jpeg_finish_decompress() after all data has been processed.  */
6673
6674static void
6675our_common_term_source (cinfo)
6676     j_decompress_ptr cinfo;
6677{
6678}
6679
6680
6681/* Fill input buffer method for JPEG data source manager.  Called
6682   whenever more data is needed.  We read the whole image in one step,
6683   so this only adds a fake end of input marker at the end.  */
6684
6685static boolean
6686our_memory_fill_input_buffer (cinfo)
6687     j_decompress_ptr cinfo;
6688{
6689  /* Insert a fake EOI marker.  */
6690  struct jpeg_source_mgr *src = cinfo->src;
6691  static JOCTET buffer[2];
6692
6693  buffer[0] = (JOCTET) 0xFF;
6694  buffer[1] = (JOCTET) JPEG_EOI;
6695
6696  src->next_input_byte = buffer;
6697  src->bytes_in_buffer = 2;
6698  return 1;
6699}
6700
6701
6702/* Method to skip over NUM_BYTES bytes in the image data.  CINFO->src
6703   is the JPEG data source manager.  */
6704
6705static void
6706our_memory_skip_input_data (cinfo, num_bytes)
6707     j_decompress_ptr cinfo;
6708     long num_bytes;
6709{
6710  struct jpeg_source_mgr *src = (struct jpeg_source_mgr *) cinfo->src;
6711
6712  if (src)
6713    {
6714      if (num_bytes > src->bytes_in_buffer)
6715	ERREXIT (cinfo, JERR_INPUT_EOF);
6716
6717      src->bytes_in_buffer -= num_bytes;
6718      src->next_input_byte += num_bytes;
6719    }
6720}
6721
6722
6723/* Set up the JPEG lib for reading an image from DATA which contains
6724   LEN bytes.  CINFO is the decompression info structure created for
6725   reading the image.  */
6726
6727static void
6728jpeg_memory_src (cinfo, data, len)
6729     j_decompress_ptr cinfo;
6730     JOCTET *data;
6731     unsigned int len;
6732{
6733  struct jpeg_source_mgr *src;
6734
6735  if (cinfo->src == NULL)
6736    {
6737      /* First time for this JPEG object?  */
6738      cinfo->src = (struct jpeg_source_mgr *)
6739	(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
6740				    sizeof (struct jpeg_source_mgr));
6741      src = (struct jpeg_source_mgr *) cinfo->src;
6742      src->next_input_byte = data;
6743    }
6744
6745  src = (struct jpeg_source_mgr *) cinfo->src;
6746  src->init_source = our_common_init_source;
6747  src->fill_input_buffer = our_memory_fill_input_buffer;
6748  src->skip_input_data = our_memory_skip_input_data;
6749  src->resync_to_restart = jpeg_resync_to_restart_wrapper; /* Use default method.  */
6750  src->term_source = our_common_term_source;
6751  src->bytes_in_buffer = len;
6752  src->next_input_byte = data;
6753}
6754
6755
6756struct jpeg_stdio_mgr
6757{
6758  struct jpeg_source_mgr mgr;
6759  boolean finished;
6760  FILE *file;
6761  JOCTET *buffer;
6762};
6763
6764
6765/* Size of buffer to read JPEG from file.
6766   Not too big, as we want to use alloc_small.  */
6767#define JPEG_STDIO_BUFFER_SIZE 8192
6768
6769
6770/* Fill input buffer method for JPEG data source manager.  Called
6771   whenever more data is needed.  The data is read from a FILE *.  */
6772
6773static boolean
6774our_stdio_fill_input_buffer (cinfo)
6775     j_decompress_ptr cinfo;
6776{
6777  struct jpeg_stdio_mgr *src;
6778
6779  src = (struct jpeg_stdio_mgr *) cinfo->src;
6780  if (!src->finished)
6781    {
6782      size_t bytes;
6783
6784      bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file);
6785      if (bytes > 0)
6786        src->mgr.bytes_in_buffer = bytes;
6787      else
6788        {
6789          WARNMS (cinfo, JWRN_JPEG_EOF);
6790          src->finished = 1;
6791          src->buffer[0] = (JOCTET) 0xFF;
6792          src->buffer[1] = (JOCTET) JPEG_EOI;
6793          src->mgr.bytes_in_buffer = 2;
6794        }
6795      src->mgr.next_input_byte = src->buffer;
6796    }
6797
6798  return 1;
6799}
6800
6801
6802/* Method to skip over NUM_BYTES bytes in the image data.  CINFO->src
6803   is the JPEG data source manager.  */
6804
6805static void
6806our_stdio_skip_input_data (cinfo, num_bytes)
6807     j_decompress_ptr cinfo;
6808     long num_bytes;
6809{
6810  struct jpeg_stdio_mgr *src;
6811  src = (struct jpeg_stdio_mgr *) cinfo->src;
6812
6813  while (num_bytes > 0 && !src->finished)
6814    {
6815      if (num_bytes <= src->mgr.bytes_in_buffer)
6816        {
6817          src->mgr.bytes_in_buffer -= num_bytes;
6818          src->mgr.next_input_byte += num_bytes;
6819          break;
6820        }
6821      else
6822        {
6823          num_bytes -= src->mgr.bytes_in_buffer;
6824          src->mgr.bytes_in_buffer = 0;
6825          src->mgr.next_input_byte = NULL;
6826
6827          our_stdio_fill_input_buffer (cinfo);
6828        }
6829    }
6830}
6831
6832
6833/* Set up the JPEG lib for reading an image from a FILE *.
6834   CINFO is the decompression info structure created for
6835   reading the image.  */
6836
6837static void
6838jpeg_file_src (cinfo, fp)
6839     j_decompress_ptr cinfo;
6840     FILE *fp;
6841{
6842  struct jpeg_stdio_mgr *src;
6843
6844  if (cinfo->src != NULL)
6845      src = (struct jpeg_stdio_mgr *) cinfo->src;
6846  else
6847    {
6848      /* First time for this JPEG object?  */
6849      cinfo->src = (struct jpeg_source_mgr *)
6850        (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
6851                                    sizeof (struct jpeg_stdio_mgr));
6852      src = (struct jpeg_stdio_mgr *) cinfo->src;
6853      src->buffer = (JOCTET *)
6854          (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
6855                                      JPEG_STDIO_BUFFER_SIZE);
6856    }
6857
6858  src->file = fp;
6859  src->finished = 0;
6860  src->mgr.init_source = our_common_init_source;
6861  src->mgr.fill_input_buffer = our_stdio_fill_input_buffer;
6862  src->mgr.skip_input_data = our_stdio_skip_input_data;
6863  src->mgr.resync_to_restart = jpeg_resync_to_restart_wrapper; /* Use default method.  */
6864  src->mgr.term_source = our_common_term_source;
6865  src->mgr.bytes_in_buffer = 0;
6866  src->mgr.next_input_byte = NULL;
6867}
6868
6869
6870/* Load image IMG for use on frame F.  Patterned after example.c
6871   from the JPEG lib.  */
6872
6873static int
6874jpeg_load (f, img)
6875     struct frame *f;
6876     struct image *img;
6877{
6878  struct jpeg_decompress_struct cinfo;
6879  struct my_jpeg_error_mgr mgr;
6880  Lisp_Object file, specified_file;
6881  Lisp_Object specified_data;
6882  FILE * volatile fp = NULL;
6883  JSAMPARRAY buffer;
6884  int row_stride, x, y;
6885  XImagePtr ximg = NULL;
6886  int rc;
6887  unsigned long *colors;
6888  int width, height;
6889  struct gcpro gcpro1;
6890
6891  /* Open the JPEG file.  */
6892  specified_file = image_spec_value (img->spec, QCfile, NULL);
6893  specified_data = image_spec_value (img->spec, QCdata, NULL);
6894  file = Qnil;
6895  GCPRO1 (file);
6896
6897  if (NILP (specified_data))
6898    {
6899      file = x_find_image_file (specified_file);
6900      if (!STRINGP (file))
6901	{
6902	  image_error ("Cannot find image file `%s'", specified_file, Qnil);
6903	  UNGCPRO;
6904	  return 0;
6905	}
6906
6907      fp = fopen (SDATA (file), "rb");
6908      if (fp == NULL)
6909	{
6910	  image_error ("Cannot open `%s'", file, Qnil);
6911	  UNGCPRO;
6912	  return 0;
6913	}
6914    }
6915
6916  /* Customize libjpeg's error handling to call my_error_exit when an
6917     error is detected.  This function will perform a longjmp.
6918     Casting return value avoids a GCC warning on W32.  */
6919  cinfo.err = (struct jpeg_error_mgr *)fn_jpeg_std_error (&mgr.pub);
6920  mgr.pub.error_exit = my_error_exit;
6921
6922  if ((rc = setjmp (mgr.setjmp_buffer)) != 0)
6923    {
6924      if (rc == 1)
6925	{
6926	  /* Called from my_error_exit.  Display a JPEG error.  */
6927	  char buffer[JMSG_LENGTH_MAX];
6928	  cinfo.err->format_message ((j_common_ptr) &cinfo, buffer);
6929	  image_error ("Error reading JPEG image `%s': %s", img->spec,
6930		       build_string (buffer));
6931	}
6932
6933      /* Close the input file and destroy the JPEG object.  */
6934      if (fp)
6935	fclose ((FILE *) fp);
6936      fn_jpeg_destroy_decompress (&cinfo);
6937
6938      /* If we already have an XImage, free that.  */
6939      x_destroy_x_image (ximg);
6940
6941      /* Free pixmap and colors.  */
6942      x_clear_image (f, img);
6943
6944      UNGCPRO;
6945      return 0;
6946    }
6947
6948  /* Create the JPEG decompression object.  Let it read from fp.
6949	 Read the JPEG image header.  */
6950  fn_jpeg_CreateDecompress (&cinfo, JPEG_LIB_VERSION, sizeof (cinfo));
6951
6952  if (NILP (specified_data))
6953    jpeg_file_src (&cinfo, (FILE *) fp);
6954  else
6955    jpeg_memory_src (&cinfo, SDATA (specified_data),
6956		     SBYTES (specified_data));
6957
6958  fn_jpeg_read_header (&cinfo, 1);
6959
6960  /* Customize decompression so that color quantization will be used.
6961	 Start decompression.  */
6962  cinfo.quantize_colors = 1;
6963  fn_jpeg_start_decompress (&cinfo);
6964  width = img->width = cinfo.output_width;
6965  height = img->height = cinfo.output_height;
6966
6967  if (!check_image_size (f, width, height))
6968    {
6969      image_error ("Invalid image size", Qnil, Qnil);
6970      longjmp (mgr.setjmp_buffer, 2);
6971    }
6972
6973  /* Create X image and pixmap.  */
6974  if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
6975    longjmp (mgr.setjmp_buffer, 2);
6976
6977  /* Allocate colors.  When color quantization is used,
6978     cinfo.actual_number_of_colors has been set with the number of
6979     colors generated, and cinfo.colormap is a two-dimensional array
6980     of color indices in the range 0..cinfo.actual_number_of_colors.
6981     No more than 255 colors will be generated.  */
6982  {
6983    int i, ir, ig, ib;
6984
6985    if (cinfo.out_color_components > 2)
6986      ir = 0, ig = 1, ib = 2;
6987    else if (cinfo.out_color_components > 1)
6988      ir = 0, ig = 1, ib = 0;
6989    else
6990      ir = 0, ig = 0, ib = 0;
6991
6992    /* Use the color table mechanism because it handles colors that
6993       cannot be allocated nicely.  Such colors will be replaced with
6994       a default color, and we don't have to care about which colors
6995       can be freed safely, and which can't.  */
6996    init_color_table ();
6997    colors = (unsigned long *) alloca (cinfo.actual_number_of_colors
6998				       * sizeof *colors);
6999
7000    for (i = 0; i < cinfo.actual_number_of_colors; ++i)
7001      {
7002	/* Multiply RGB values with 255 because X expects RGB values
7003	   in the range 0..0xffff.  */
7004	int r = cinfo.colormap[ir][i] << 8;
7005	int g = cinfo.colormap[ig][i] << 8;
7006	int b = cinfo.colormap[ib][i] << 8;
7007	colors[i] = lookup_rgb_color (f, r, g, b);
7008      }
7009
7010#ifdef COLOR_TABLE_SUPPORT
7011    /* Remember those colors actually allocated.  */
7012    img->colors = colors_in_color_table (&img->ncolors);
7013    free_color_table ();
7014#endif /* COLOR_TABLE_SUPPORT */
7015  }
7016
7017  /* Read pixels.  */
7018  row_stride = width * cinfo.output_components;
7019  buffer = cinfo.mem->alloc_sarray ((j_common_ptr) &cinfo, JPOOL_IMAGE,
7020				    row_stride, 1);
7021  for (y = 0; y < height; ++y)
7022    {
7023      fn_jpeg_read_scanlines (&cinfo, buffer, 1);
7024      for (x = 0; x < cinfo.output_width; ++x)
7025	XPutPixel (ximg, x, y, colors[buffer[0][x]]);
7026    }
7027
7028  /* Clean up.  */
7029  fn_jpeg_finish_decompress (&cinfo);
7030  fn_jpeg_destroy_decompress (&cinfo);
7031  if (fp)
7032    fclose ((FILE *) fp);
7033
7034  /* Maybe fill in the background field while we have ximg handy. */
7035  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7036    /* Casting avoids a GCC warning.  */
7037    IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
7038
7039  /* Put the image into the pixmap.  */
7040  x_put_x_image (f, ximg, img->pixmap, width, height);
7041  x_destroy_x_image (ximg);
7042  UNGCPRO;
7043  return 1;
7044}
7045
7046#else /* HAVE_JPEG */
7047
7048#ifdef MAC_OS
7049static int
7050jpeg_load (f, img)
7051     struct frame *f;
7052     struct image *img;
7053{
7054#ifdef MAC_OSX
7055  return image_load_quartz2d (f, img, 0);
7056#else
7057  return image_load_quicktime (f, img, kQTFileTypeJPEG);
7058#endif
7059}
7060#endif  /* MAC_OS */
7061
7062#endif /* !HAVE_JPEG */
7063
7064
7065
7066/***********************************************************************
7067				 TIFF
7068 ***********************************************************************/
7069
7070#if defined (HAVE_TIFF) || defined (MAC_OS)
7071
7072static int tiff_image_p P_ ((Lisp_Object object));
7073static int tiff_load P_ ((struct frame *f, struct image *img));
7074
7075/* The symbol `tiff' identifying images of this type.  */
7076
7077Lisp_Object Qtiff;
7078
7079/* Indices of image specification fields in tiff_format, below.  */
7080
7081enum tiff_keyword_index
7082{
7083  TIFF_TYPE,
7084  TIFF_DATA,
7085  TIFF_FILE,
7086  TIFF_ASCENT,
7087  TIFF_MARGIN,
7088  TIFF_RELIEF,
7089  TIFF_ALGORITHM,
7090  TIFF_HEURISTIC_MASK,
7091  TIFF_MASK,
7092  TIFF_BACKGROUND,
7093  TIFF_LAST
7094};
7095
7096/* Vector of image_keyword structures describing the format
7097   of valid user-defined image specifications.  */
7098
7099static struct image_keyword tiff_format[TIFF_LAST] =
7100{
7101  {":type",		IMAGE_SYMBOL_VALUE,			1},
7102  {":data",		IMAGE_STRING_VALUE,			0},
7103  {":file",		IMAGE_STRING_VALUE,			0},
7104  {":ascent",		IMAGE_ASCENT_VALUE,			0},
7105  {":margin",		IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,	0},
7106  {":relief",		IMAGE_INTEGER_VALUE,			0},
7107  {":conversions",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
7108  {":heuristic-mask",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
7109  {":mask",		IMAGE_DONT_CHECK_VALUE_TYPE,		0},
7110  {":background",	IMAGE_STRING_OR_NIL_VALUE,		0}
7111};
7112
7113/* Structure describing the image type `tiff'.  */
7114
7115static struct image_type tiff_type =
7116{
7117  &Qtiff,
7118  tiff_image_p,
7119  tiff_load,
7120  x_clear_image,
7121  NULL
7122};
7123
7124/* Return non-zero if OBJECT is a valid TIFF image specification.  */
7125
7126static int
7127tiff_image_p (object)
7128     Lisp_Object object;
7129{
7130  struct image_keyword fmt[TIFF_LAST];
7131  bcopy (tiff_format, fmt, sizeof fmt);
7132
7133  if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff))
7134    return 0;
7135
7136  /* Must specify either the :data or :file keyword.  */
7137  return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1;
7138}
7139
7140#endif /* HAVE_TIFF || MAC_OS */
7141
7142#ifdef HAVE_TIFF
7143
7144#include <tiffio.h>
7145
7146#ifdef HAVE_NTGUI
7147
7148/* TIFF library details.  */
7149DEF_IMGLIB_FN (TIFFSetErrorHandler);
7150DEF_IMGLIB_FN (TIFFSetWarningHandler);
7151DEF_IMGLIB_FN (TIFFOpen);
7152DEF_IMGLIB_FN (TIFFClientOpen);
7153DEF_IMGLIB_FN (TIFFGetField);
7154DEF_IMGLIB_FN (TIFFReadRGBAImage);
7155DEF_IMGLIB_FN (TIFFClose);
7156
7157static int
7158init_tiff_functions (Lisp_Object libraries)
7159{
7160  HMODULE library;
7161
7162  if (!(library = w32_delayed_load (libraries, Qtiff)))
7163    return 0;
7164
7165  LOAD_IMGLIB_FN (library, TIFFSetErrorHandler);
7166  LOAD_IMGLIB_FN (library, TIFFSetWarningHandler);
7167  LOAD_IMGLIB_FN (library, TIFFOpen);
7168  LOAD_IMGLIB_FN (library, TIFFClientOpen);
7169  LOAD_IMGLIB_FN (library, TIFFGetField);
7170  LOAD_IMGLIB_FN (library, TIFFReadRGBAImage);
7171  LOAD_IMGLIB_FN (library, TIFFClose);
7172  return 1;
7173}
7174
7175#else
7176
7177#define fn_TIFFSetErrorHandler		TIFFSetErrorHandler
7178#define fn_TIFFSetWarningHandler	TIFFSetWarningHandler
7179#define fn_TIFFOpen			TIFFOpen
7180#define fn_TIFFClientOpen		TIFFClientOpen
7181#define fn_TIFFGetField			TIFFGetField
7182#define fn_TIFFReadRGBAImage		TIFFReadRGBAImage
7183#define fn_TIFFClose			TIFFClose
7184
7185#endif /* HAVE_NTGUI */
7186
7187
7188/* Reading from a memory buffer for TIFF images Based on the PNG
7189   memory source, but we have to provide a lot of extra functions.
7190   Blah.
7191
7192   We really only need to implement read and seek, but I am not
7193   convinced that the TIFF library is smart enough not to destroy
7194   itself if we only hand it the function pointers we need to
7195   override.  */
7196
7197typedef struct
7198{
7199  unsigned char *bytes;
7200  size_t len;
7201  int index;
7202}
7203tiff_memory_source;
7204
7205static size_t
7206tiff_read_from_memory (data, buf, size)
7207     thandle_t data;
7208     tdata_t buf;
7209     tsize_t size;
7210{
7211  tiff_memory_source *src = (tiff_memory_source *) data;
7212
7213  if (size > src->len - src->index)
7214    return (size_t) -1;
7215  bcopy (src->bytes + src->index, buf, size);
7216  src->index += size;
7217  return size;
7218}
7219
7220static size_t
7221tiff_write_from_memory (data, buf, size)
7222     thandle_t data;
7223     tdata_t buf;
7224     tsize_t size;
7225{
7226  return (size_t) -1;
7227}
7228
7229static toff_t
7230tiff_seek_in_memory (data, off, whence)
7231     thandle_t data;
7232     toff_t off;
7233     int whence;
7234{
7235  tiff_memory_source *src = (tiff_memory_source *) data;
7236  int idx;
7237
7238  switch (whence)
7239    {
7240    case SEEK_SET:		/* Go from beginning of source.  */
7241      idx = off;
7242      break;
7243
7244    case SEEK_END:		/* Go from end of source.  */
7245      idx = src->len + off;
7246      break;
7247
7248    case SEEK_CUR:		/* Go from current position.  */
7249      idx = src->index + off;
7250      break;
7251
7252    default:			/* Invalid `whence'.   */
7253      return -1;
7254    }
7255
7256  if (idx > src->len || idx < 0)
7257    return -1;
7258
7259  src->index = idx;
7260  return src->index;
7261}
7262
7263static int
7264tiff_close_memory (data)
7265     thandle_t data;
7266{
7267  /* NOOP */
7268  return 0;
7269}
7270
7271static int
7272tiff_mmap_memory (data, pbase, psize)
7273     thandle_t data;
7274     tdata_t *pbase;
7275     toff_t *psize;
7276{
7277  /* It is already _IN_ memory. */
7278  return 0;
7279}
7280
7281static void
7282tiff_unmap_memory (data, base, size)
7283     thandle_t data;
7284     tdata_t base;
7285     toff_t size;
7286{
7287  /* We don't need to do this. */
7288}
7289
7290static toff_t
7291tiff_size_of_memory (data)
7292     thandle_t data;
7293{
7294  return ((tiff_memory_source *) data)->len;
7295}
7296
7297
7298static void
7299tiff_error_handler (title, format, ap)
7300     const char *title, *format;
7301     va_list ap;
7302{
7303  char buf[512];
7304  int len;
7305
7306  len = sprintf (buf, "TIFF error: %s ", title);
7307  vsprintf (buf + len, format, ap);
7308  add_to_log (buf, Qnil, Qnil);
7309}
7310
7311
7312static void
7313tiff_warning_handler (title, format, ap)
7314     const char *title, *format;
7315     va_list ap;
7316{
7317  char buf[512];
7318  int len;
7319
7320  len = sprintf (buf, "TIFF warning: %s ", title);
7321  vsprintf (buf + len, format, ap);
7322  add_to_log (buf, Qnil, Qnil);
7323}
7324
7325
7326/* Load TIFF image IMG for use on frame F.  Value is non-zero if
7327   successful.  */
7328
7329static int
7330tiff_load (f, img)
7331     struct frame *f;
7332     struct image *img;
7333{
7334  Lisp_Object file, specified_file;
7335  Lisp_Object specified_data;
7336  TIFF *tiff;
7337  int width, height, x, y;
7338  uint32 *buf;
7339  int rc;
7340  XImagePtr ximg;
7341  struct gcpro gcpro1;
7342  tiff_memory_source memsrc;
7343
7344  specified_file = image_spec_value (img->spec, QCfile, NULL);
7345  specified_data = image_spec_value (img->spec, QCdata, NULL);
7346  file = Qnil;
7347  GCPRO1 (file);
7348
7349  fn_TIFFSetErrorHandler (tiff_error_handler);
7350  fn_TIFFSetWarningHandler (tiff_warning_handler);
7351
7352  if (NILP (specified_data))
7353    {
7354      /* Read from a file */
7355      file = x_find_image_file (specified_file);
7356      if (!STRINGP (file))
7357	{
7358	  image_error ("Cannot find image file `%s'", specified_file, Qnil);
7359	  UNGCPRO;
7360	  return 0;
7361	}
7362
7363      /* Try to open the image file.  Casting return value avoids a
7364	 GCC warning on W32.  */
7365      tiff = (TIFF *)fn_TIFFOpen (SDATA (file), "r");
7366      if (tiff == NULL)
7367	{
7368	  image_error ("Cannot open `%s'", file, Qnil);
7369	  UNGCPRO;
7370	  return 0;
7371	}
7372    }
7373  else
7374    {
7375      /* Memory source! */
7376      memsrc.bytes = SDATA (specified_data);
7377      memsrc.len = SBYTES (specified_data);
7378      memsrc.index = 0;
7379
7380      /* Casting return value avoids a GCC warning on W32.  */
7381      tiff = (TIFF *)fn_TIFFClientOpen ("memory_source", "r", &memsrc,
7382					(TIFFReadWriteProc) tiff_read_from_memory,
7383					(TIFFReadWriteProc) tiff_write_from_memory,
7384					tiff_seek_in_memory,
7385					tiff_close_memory,
7386					tiff_size_of_memory,
7387					tiff_mmap_memory,
7388					tiff_unmap_memory);
7389
7390      if (!tiff)
7391	{
7392	  image_error ("Cannot open memory source for `%s'", img->spec, Qnil);
7393	  UNGCPRO;
7394	  return 0;
7395	}
7396    }
7397
7398  /* Get width and height of the image, and allocate a raster buffer
7399     of width x height 32-bit values.  */
7400  fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
7401  fn_TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
7402
7403  if (!check_image_size (f, width, height))
7404    {
7405      image_error ("Invalid image size", Qnil, Qnil);
7406      UNGCPRO;
7407      return 0;
7408    }
7409
7410  buf = (uint32 *) xmalloc (width * height * sizeof *buf);
7411
7412  rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
7413  fn_TIFFClose (tiff);
7414  if (!rc)
7415    {
7416      image_error ("Error reading TIFF image `%s'", img->spec, Qnil);
7417      xfree (buf);
7418      UNGCPRO;
7419      return 0;
7420    }
7421
7422  /* Create the X image and pixmap.  */
7423  if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
7424    {
7425      xfree (buf);
7426      UNGCPRO;
7427      return 0;
7428    }
7429
7430  /* Initialize the color table.  */
7431  init_color_table ();
7432
7433  /* Process the pixel raster.  Origin is in the lower-left corner.  */
7434  for (y = 0; y < height; ++y)
7435    {
7436      uint32 *row = buf + y * width;
7437
7438      for (x = 0; x < width; ++x)
7439	{
7440	  uint32 abgr = row[x];
7441	  int r = TIFFGetR (abgr) << 8;
7442	  int g = TIFFGetG (abgr) << 8;
7443	  int b = TIFFGetB (abgr) << 8;
7444	  XPutPixel (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b));
7445	}
7446    }
7447
7448#ifdef COLOR_TABLE_SUPPORT
7449  /* Remember the colors allocated for the image.  Free the color table.  */
7450  img->colors = colors_in_color_table (&img->ncolors);
7451  free_color_table ();
7452#endif /* COLOR_TABLE_SUPPORT */
7453
7454  img->width = width;
7455  img->height = height;
7456
7457  /* Maybe fill in the background field while we have ximg handy. */
7458  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7459    /* Casting avoids a GCC warning on W32.  */
7460    IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
7461
7462  /* Put the image into the pixmap, then free the X image and its buffer.  */
7463  x_put_x_image (f, ximg, img->pixmap, width, height);
7464  x_destroy_x_image (ximg);
7465  xfree (buf);
7466
7467  UNGCPRO;
7468  return 1;
7469}
7470
7471#else /* HAVE_TIFF */
7472
7473#ifdef MAC_OS
7474static int
7475tiff_load (f, img)
7476     struct frame *f;
7477     struct image *img;
7478{
7479  return image_load_quicktime (f, img, kQTFileTypeTIFF);
7480}
7481#endif /* MAC_OS */
7482
7483#endif /* !HAVE_TIFF */
7484
7485
7486
7487/***********************************************************************
7488				 GIF
7489 ***********************************************************************/
7490
7491#if defined (HAVE_GIF) || defined (MAC_OS)
7492
7493static int gif_image_p P_ ((Lisp_Object object));
7494static int gif_load P_ ((struct frame *f, struct image *img));
7495static void gif_clear_image P_ ((struct frame *f, struct image *img));
7496
7497/* The symbol `gif' identifying images of this type.  */
7498
7499Lisp_Object Qgif;
7500
7501/* Indices of image specification fields in gif_format, below.  */
7502
7503enum gif_keyword_index
7504{
7505  GIF_TYPE,
7506  GIF_DATA,
7507  GIF_FILE,
7508  GIF_ASCENT,
7509  GIF_MARGIN,
7510  GIF_RELIEF,
7511  GIF_ALGORITHM,
7512  GIF_HEURISTIC_MASK,
7513  GIF_MASK,
7514  GIF_IMAGE,
7515  GIF_BACKGROUND,
7516  GIF_LAST
7517};
7518
7519/* Vector of image_keyword structures describing the format
7520   of valid user-defined image specifications.  */
7521
7522static struct image_keyword gif_format[GIF_LAST] =
7523{
7524  {":type",		IMAGE_SYMBOL_VALUE,			1},
7525  {":data",		IMAGE_STRING_VALUE,			0},
7526  {":file",		IMAGE_STRING_VALUE,			0},
7527  {":ascent",		IMAGE_ASCENT_VALUE,			0},
7528  {":margin",		IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,	0},
7529  {":relief",		IMAGE_INTEGER_VALUE,			0},
7530  {":conversion",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
7531  {":heuristic-mask",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
7532  {":mask",		IMAGE_DONT_CHECK_VALUE_TYPE,		0},
7533  {":image",		IMAGE_NON_NEGATIVE_INTEGER_VALUE,	0},
7534  {":background",	IMAGE_STRING_OR_NIL_VALUE,		0}
7535};
7536
7537/* Structure describing the image type `gif'.  */
7538
7539static struct image_type gif_type =
7540{
7541  &Qgif,
7542  gif_image_p,
7543  gif_load,
7544  gif_clear_image,
7545  NULL
7546};
7547
7548/* Free X resources of GIF image IMG which is used on frame F.  */
7549
7550static void
7551gif_clear_image (f, img)
7552     struct frame *f;
7553     struct image *img;
7554{
7555  /* IMG->data.ptr_val may contain extension data.  */
7556  img->data.lisp_val = Qnil;
7557  x_clear_image (f, img);
7558}
7559
7560/* Return non-zero if OBJECT is a valid GIF image specification.  */
7561
7562static int
7563gif_image_p (object)
7564     Lisp_Object object;
7565{
7566  struct image_keyword fmt[GIF_LAST];
7567  bcopy (gif_format, fmt, sizeof fmt);
7568
7569  if (!parse_image_spec (object, fmt, GIF_LAST, Qgif))
7570    return 0;
7571
7572  /* Must specify either the :data or :file keyword.  */
7573  return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1;
7574}
7575
7576#endif /* HAVE_GIF || MAC_OS */
7577
7578#ifdef HAVE_GIF
7579
7580#if defined (HAVE_NTGUI) || defined (MAC_OS)
7581/* winuser.h might define DrawText to DrawTextA or DrawTextW.
7582   Undefine before redefining to avoid a preprocessor warning.  */
7583#ifdef DrawText
7584#undef DrawText
7585#endif
7586/* avoid conflict with QuickdrawText.h */
7587#define DrawText gif_DrawText
7588#include <gif_lib.h>
7589#undef DrawText
7590
7591#else /* HAVE_NTGUI || MAC_OS */
7592
7593#include <gif_lib.h>
7594
7595#endif /* HAVE_NTGUI || MAC_OS */
7596
7597
7598#ifdef HAVE_NTGUI
7599
7600/* GIF library details.  */
7601DEF_IMGLIB_FN (DGifCloseFile);
7602DEF_IMGLIB_FN (DGifSlurp);
7603DEF_IMGLIB_FN (DGifOpen);
7604DEF_IMGLIB_FN (DGifOpenFileName);
7605
7606static int
7607init_gif_functions (Lisp_Object libraries)
7608{
7609  HMODULE library;
7610
7611  if (!(library = w32_delayed_load (libraries, Qgif)))
7612    return 0;
7613
7614  LOAD_IMGLIB_FN (library, DGifCloseFile);
7615  LOAD_IMGLIB_FN (library, DGifSlurp);
7616  LOAD_IMGLIB_FN (library, DGifOpen);
7617  LOAD_IMGLIB_FN (library, DGifOpenFileName);
7618  return 1;
7619}
7620
7621#else
7622
7623#define fn_DGifCloseFile	DGifCloseFile
7624#define fn_DGifSlurp		DGifSlurp
7625#define fn_DGifOpen		DGifOpen
7626#define fn_DGifOpenFileName	DGifOpenFileName
7627
7628#endif /* HAVE_NTGUI */
7629
7630/* Reading a GIF image from memory
7631   Based on the PNG memory stuff to a certain extent. */
7632
7633typedef struct
7634{
7635  unsigned char *bytes;
7636  size_t len;
7637  int index;
7638}
7639gif_memory_source;
7640
7641/* Make the current memory source available to gif_read_from_memory.
7642   It's done this way because not all versions of libungif support
7643   a UserData field in the GifFileType structure.  */
7644static gif_memory_source *current_gif_memory_src;
7645
7646static int
7647gif_read_from_memory (file, buf, len)
7648     GifFileType *file;
7649     GifByteType *buf;
7650     int len;
7651{
7652  gif_memory_source *src = current_gif_memory_src;
7653
7654  if (len > src->len - src->index)
7655    return -1;
7656
7657  bcopy (src->bytes + src->index, buf, len);
7658  src->index += len;
7659  return len;
7660}
7661
7662
7663/* Load GIF image IMG for use on frame F.  Value is non-zero if
7664   successful.  */
7665
7666static int
7667gif_load (f, img)
7668     struct frame *f;
7669     struct image *img;
7670{
7671  Lisp_Object file, specified_file;
7672  Lisp_Object specified_data;
7673  int rc, width, height, x, y, i;
7674  XImagePtr ximg;
7675  ColorMapObject *gif_color_map;
7676  unsigned long pixel_colors[256];
7677  GifFileType *gif;
7678  struct gcpro gcpro1;
7679  Lisp_Object image;
7680  int ino, image_height, image_width;
7681  gif_memory_source memsrc;
7682  unsigned char *raster;
7683
7684  specified_file = image_spec_value (img->spec, QCfile, NULL);
7685  specified_data = image_spec_value (img->spec, QCdata, NULL);
7686  file = Qnil;
7687  GCPRO1 (file);
7688
7689  if (NILP (specified_data))
7690    {
7691      file = x_find_image_file (specified_file);
7692      if (!STRINGP (file))
7693	{
7694	  image_error ("Cannot find image file `%s'", specified_file, Qnil);
7695	  UNGCPRO;
7696	  return 0;
7697	}
7698
7699      /* Open the GIF file.  Casting return value avoids a GCC warning
7700	 on W32.  */
7701      gif = (GifFileType *)fn_DGifOpenFileName (SDATA (file));
7702      if (gif == NULL)
7703	{
7704	  image_error ("Cannot open `%s'", file, Qnil);
7705	  UNGCPRO;
7706	  return 0;
7707	}
7708    }
7709  else
7710    {
7711      /* Read from memory! */
7712      current_gif_memory_src = &memsrc;
7713      memsrc.bytes = SDATA (specified_data);
7714      memsrc.len = SBYTES (specified_data);
7715      memsrc.index = 0;
7716
7717      /* Casting return value avoids a GCC warning on W32.  */
7718      gif = (GifFileType *)fn_DGifOpen(&memsrc, gif_read_from_memory);
7719      if (!gif)
7720	{
7721	  image_error ("Cannot open memory source `%s'", img->spec, Qnil);
7722	  UNGCPRO;
7723	  return 0;
7724	}
7725    }
7726
7727  /* Before reading entire contents, check the declared image size. */
7728  if (!check_image_size (f, gif->SWidth, gif->SHeight))
7729    {
7730      image_error ("Invalid image size", Qnil, Qnil);
7731      fn_DGifCloseFile (gif);
7732      UNGCPRO;
7733      return 0;
7734    }
7735
7736  /* Read entire contents.  */
7737  rc = fn_DGifSlurp (gif);
7738  if (rc == GIF_ERROR)
7739    {
7740      image_error ("Error reading `%s'", img->spec, Qnil);
7741      fn_DGifCloseFile (gif);
7742      UNGCPRO;
7743      return 0;
7744    }
7745
7746  image = image_spec_value (img->spec, QCindex, NULL);
7747  ino = INTEGERP (image) ? XFASTINT (image) : 0;
7748  if (ino >= gif->ImageCount)
7749    {
7750      image_error ("Invalid image number `%s' in image `%s'",
7751		   image, img->spec);
7752      fn_DGifCloseFile (gif);
7753      UNGCPRO;
7754      return 0;
7755    }
7756
7757  img->corners[TOP_CORNER] = gif->SavedImages[ino].ImageDesc.Top;
7758  img->corners[LEFT_CORNER] = gif->SavedImages[ino].ImageDesc.Left;
7759  image_height = gif->SavedImages[ino].ImageDesc.Height;
7760  img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + image_height;
7761  image_width = gif->SavedImages[ino].ImageDesc.Width;
7762  img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + image_width;
7763
7764  width = img->width = max (gif->SWidth,
7765			    max (gif->Image.Left + gif->Image.Width,
7766				 img->corners[RIGHT_CORNER]));
7767  height = img->height = max (gif->SHeight,
7768			      max (gif->Image.Top + gif->Image.Height,
7769				   img->corners[BOT_CORNER]));
7770
7771  if (!check_image_size (f, width, height))
7772    {
7773      image_error ("Invalid image size", Qnil, Qnil);
7774      fn_DGifCloseFile (gif);
7775      UNGCPRO;
7776      return 0;
7777    }
7778
7779  /* Create the X image and pixmap.  */
7780  if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
7781    {
7782      fn_DGifCloseFile (gif);
7783      UNGCPRO;
7784      return 0;
7785    }
7786
7787  /* Allocate colors.  */
7788  gif_color_map = gif->SavedImages[ino].ImageDesc.ColorMap;
7789  if (!gif_color_map)
7790    gif_color_map = gif->SColorMap;
7791  init_color_table ();
7792  bzero (pixel_colors, sizeof pixel_colors);
7793
7794  for (i = 0; i < gif_color_map->ColorCount; ++i)
7795    {
7796      int r = gif_color_map->Colors[i].Red << 8;
7797      int g = gif_color_map->Colors[i].Green << 8;
7798      int b = gif_color_map->Colors[i].Blue << 8;
7799      pixel_colors[i] = lookup_rgb_color (f, r, g, b);
7800    }
7801
7802#ifdef COLOR_TABLE_SUPPORT
7803  img->colors = colors_in_color_table (&img->ncolors);
7804  free_color_table ();
7805#endif /* COLOR_TABLE_SUPPORT */
7806
7807  /* Clear the part of the screen image that are not covered by
7808     the image from the GIF file.  Full animated GIF support
7809     requires more than can be done here (see the gif89 spec,
7810     disposal methods).  Let's simply assume that the part
7811     not covered by a sub-image is in the frame's background color.  */
7812  for (y = 0; y < img->corners[TOP_CORNER]; ++y)
7813    for (x = 0; x < width; ++x)
7814      XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7815
7816  for (y = img->corners[BOT_CORNER]; y < height; ++y)
7817    for (x = 0; x < width; ++x)
7818      XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7819
7820  for (y = img->corners[TOP_CORNER]; y < img->corners[BOT_CORNER]; ++y)
7821    {
7822      for (x = 0; x < img->corners[LEFT_CORNER]; ++x)
7823	XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7824      for (x = img->corners[RIGHT_CORNER]; x < width; ++x)
7825	XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7826    }
7827
7828  /* Read the GIF image into the X image.  We use a local variable
7829     `raster' here because RasterBits below is a char *, and invites
7830     problems with bytes >= 0x80.  */
7831  raster = (unsigned char *) gif->SavedImages[ino].RasterBits;
7832
7833  if (gif->SavedImages[ino].ImageDesc.Interlace)
7834    {
7835      static int interlace_start[] = {0, 4, 2, 1};
7836      static int interlace_increment[] = {8, 8, 4, 2};
7837      int pass;
7838      int row = interlace_start[0];
7839
7840      pass = 0;
7841
7842      for (y = 0; y < image_height; y++)
7843	{
7844	  if (row >= image_height)
7845	    {
7846	      row = interlace_start[++pass];
7847	      while (row >= image_height)
7848		row = interlace_start[++pass];
7849	    }
7850
7851	  for (x = 0; x < image_width; x++)
7852	    {
7853	      int i = raster[(y * image_width) + x];
7854	      XPutPixel (ximg, x + img->corners[LEFT_CORNER],
7855			 row + img->corners[TOP_CORNER], pixel_colors[i]);
7856	    }
7857
7858	  row += interlace_increment[pass];
7859	}
7860    }
7861  else
7862    {
7863      for (y = 0; y < image_height; ++y)
7864	for (x = 0; x < image_width; ++x)
7865	  {
7866	    int i = raster[y * image_width + x];
7867	    XPutPixel (ximg, x + img->corners[LEFT_CORNER],
7868		       y + img->corners[TOP_CORNER], pixel_colors[i]);
7869	  }
7870    }
7871
7872  /* Save GIF image extension data for `image-extension-data'.
7873     Format is (count IMAGES FUNCTION "BYTES" ...).  */
7874  img->data.lisp_val = Qnil;
7875  if (gif->SavedImages[ino].ExtensionBlockCount > 0)
7876    {
7877      ExtensionBlock *ext = gif->SavedImages[ino].ExtensionBlocks;
7878      for (i = 0; i < gif->SavedImages[ino].ExtensionBlockCount; i++, ext++)
7879	/* Append (... FUNCTION "BYTES") */
7880	img->data.lisp_val = Fcons (make_unibyte_string (ext->Bytes, ext->ByteCount),
7881				    Fcons (make_number (ext->Function),
7882					   img->data.lisp_val));
7883      img->data.lisp_val = Fnreverse (img->data.lisp_val);
7884    }
7885  if (gif->ImageCount > 1)
7886    img->data.lisp_val = Fcons (Qcount,
7887				Fcons (make_number (gif->ImageCount),
7888				       img->data.lisp_val));
7889
7890  fn_DGifCloseFile (gif);
7891
7892  /* Maybe fill in the background field while we have ximg handy. */
7893  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7894    /* Casting avoids a GCC warning.  */
7895    IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
7896
7897  /* Put the image into the pixmap, then free the X image and its buffer.  */
7898  x_put_x_image (f, ximg, img->pixmap, width, height);
7899  x_destroy_x_image (ximg);
7900
7901  UNGCPRO;
7902  return 1;
7903}
7904
7905#else  /* !HAVE_GIF */
7906
7907#ifdef MAC_OS
7908static int
7909gif_load (f, img)
7910     struct frame *f;
7911     struct image *img;
7912{
7913  Lisp_Object specified_file, file;
7914  Lisp_Object specified_data;
7915  OSErr err;
7916  Boolean graphic_p, movie_p, prefer_graphic_p;
7917  Handle dh = NULL;
7918  Movie movie = NULL;
7919  Lisp_Object image;
7920  Track track = NULL;
7921  Media media = NULL;
7922  long nsamples;
7923  Rect rect;
7924  Lisp_Object specified_bg;
7925  XColor color;
7926  RGBColor bg_color;
7927  int width, height;
7928  XImagePtr ximg;
7929  TimeScale time_scale;
7930  TimeValue time, duration;
7931  int ino;
7932  CGrafPtr old_port;
7933  GDHandle old_gdh;
7934
7935  specified_file = image_spec_value (img->spec, QCfile, NULL);
7936  specified_data = image_spec_value (img->spec, QCdata, NULL);
7937
7938  /* Animated gifs use QuickTime Movie Toolbox.  So initialize it here. */
7939  EnterMovies ();
7940
7941  if (NILP (specified_data))
7942    {
7943      /* Read from a file */
7944      FSSpec fss;
7945      short refnum;
7946
7947      err = find_image_fsspec (specified_file, &file, &fss);
7948      if (err != noErr)
7949	{
7950	  if (err == fnfErr)
7951	    image_error ("Cannot find image file `%s'", specified_file, Qnil);
7952	  else
7953	    goto open_error;
7954	}
7955
7956      err = CanQuickTimeOpenFile (&fss, kQTFileTypeGIF, 0,
7957				  &graphic_p, &movie_p, &prefer_graphic_p, 0);
7958      if (err != noErr)
7959	goto open_error;
7960
7961      if (!graphic_p && !movie_p)
7962	goto open_error;
7963      if (prefer_graphic_p)
7964	return image_load_qt_1 (f, img, kQTFileTypeGIF, &fss, NULL);
7965      err = OpenMovieFile (&fss, &refnum, fsRdPerm);
7966      if (err != noErr)
7967	goto open_error;
7968      err = NewMovieFromFile (&movie, refnum, NULL, NULL, 0, NULL);
7969      CloseMovieFile (refnum);
7970      if (err != noErr)
7971	{
7972	  image_error ("Error reading `%s'", file, Qnil);
7973	  return 0;
7974	}
7975    }
7976  else
7977    {
7978      /* Memory source! */
7979      Handle dref = NULL;
7980      long file_type_atom[3];
7981
7982      err = PtrToHand (SDATA (specified_data), &dh, SBYTES (specified_data));
7983      if (err != noErr)
7984	{
7985	  image_error ("Cannot allocate data handle for `%s'",
7986		       img->spec, Qnil);
7987	  goto error;
7988	}
7989
7990      file_type_atom[0] = EndianU32_NtoB (sizeof (long) * 3);
7991      file_type_atom[1] = EndianU32_NtoB (kDataRefExtensionMacOSFileType);
7992      file_type_atom[2] = EndianU32_NtoB (kQTFileTypeGIF);
7993      err = PtrToHand (&dh, &dref, sizeof (Handle));
7994      if (err == noErr)
7995	/* no file name */
7996	err = PtrAndHand ("\p", dref, 1);
7997      if (err == noErr)
7998	err = PtrAndHand (file_type_atom, dref, sizeof (long) * 3);
7999      if (err != noErr)
8000	{
8001	  image_error ("Cannot allocate handle data ref for `%s'", img->spec, Qnil);
8002	  goto error;
8003	}
8004      err = CanQuickTimeOpenDataRef (dref, HandleDataHandlerSubType, &graphic_p,
8005				     &movie_p, &prefer_graphic_p, 0);
8006      if (err != noErr)
8007	goto open_error;
8008
8009      if (!graphic_p && !movie_p)
8010	goto open_error;
8011      if (prefer_graphic_p)
8012	{
8013	  int success_p;
8014
8015	  DisposeHandle (dref);
8016	  success_p = image_load_qt_1 (f, img, kQTFileTypeGIF, NULL, dh);
8017	  DisposeHandle (dh);
8018	  return success_p;
8019	}
8020      err = NewMovieFromDataRef (&movie, 0, NULL, dref,
8021				 HandleDataHandlerSubType);
8022      DisposeHandle (dref);
8023      if (err != noErr)
8024	goto open_error;
8025    }
8026
8027  image = image_spec_value (img->spec, QCindex, NULL);
8028  ino = INTEGERP (image) ? XFASTINT (image) : 0;
8029  track = GetMovieIndTrack (movie, 1);
8030  media = GetTrackMedia (track);
8031  nsamples = GetMediaSampleCount (media);
8032  if (ino >= nsamples)
8033    {
8034      image_error ("Invalid image number `%s' in image `%s'",
8035		   image, img->spec);
8036      goto error;
8037    }
8038  time_scale = GetMediaTimeScale (media);
8039
8040  specified_bg = image_spec_value (img->spec, QCbackground, NULL);
8041  if (!STRINGP (specified_bg) ||
8042      !mac_defined_color (f, SDATA (specified_bg), &color, 0))
8043    {
8044      color.pixel = FRAME_BACKGROUND_PIXEL (f);
8045      color.red = RED16_FROM_ULONG (color.pixel);
8046      color.green = GREEN16_FROM_ULONG (color.pixel);
8047      color.blue = BLUE16_FROM_ULONG (color.pixel);
8048    }
8049  GetMovieBox (movie, &rect);
8050  width = img->width = rect.right - rect.left;
8051  height = img->height = rect.bottom - rect.top;
8052  if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
8053    goto error;
8054
8055  GetGWorld (&old_port, &old_gdh);
8056  SetGWorld (ximg, NULL);
8057  bg_color.red = color.red;
8058  bg_color.green = color.green;
8059  bg_color.blue = color.blue;
8060  RGBBackColor (&bg_color);
8061  SetGWorld (old_port, old_gdh);
8062  SetMovieActive (movie, 1);
8063  SetMovieGWorld (movie, ximg, NULL);
8064  SampleNumToMediaTime (media, ino + 1, &time, &duration);
8065  SetMovieTimeValue (movie, time);
8066  MoviesTask (movie, 0L);
8067  DisposeTrackMedia (media);
8068  DisposeMovieTrack (track);
8069  DisposeMovie (movie);
8070  if (dh)
8071    DisposeHandle (dh);
8072
8073  /* Save GIF image extension data for `image-extension-data'.
8074     Format is (count IMAGES 0xf9 GRAPHIC_CONTROL_EXTENSION_BLOCK).  */
8075  {
8076    Lisp_Object gce = make_uninit_string (4);
8077    int centisec = ((float)duration / time_scale) * 100.0f + 0.5f;
8078
8079    /* Fill the delay time field.  */
8080    SSET (gce, 1, centisec & 0xff);
8081    SSET (gce, 2, (centisec >> 8) & 0xff);
8082    /* We don't know about other fields.  */
8083    SSET (gce, 0, 0);
8084    SSET (gce, 3, 0);
8085
8086    img->data.lisp_val = list4 (Qcount, make_number (nsamples),
8087				make_number (0xf9), gce);
8088  }
8089
8090  /* Maybe fill in the background field while we have ximg handy. */
8091  if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
8092    IMAGE_BACKGROUND (img, f, ximg);
8093
8094  /* Put the image into the pixmap.  */
8095  x_put_x_image (f, ximg, img->pixmap, width, height);
8096  x_destroy_x_image (ximg);
8097  return 1;
8098
8099 open_error:
8100  image_error ("Cannot open `%s'", file, Qnil);
8101 error:
8102  if (media)
8103    DisposeTrackMedia (media);
8104  if (track)
8105    DisposeMovieTrack (track);
8106  if (movie)
8107    DisposeMovie (movie);
8108  if (dh)
8109    DisposeHandle (dh);
8110  return 0;
8111}
8112#endif /* MAC_OS */
8113
8114#endif /* HAVE_GIF */
8115
8116
8117
8118/***********************************************************************
8119				Ghostscript
8120 ***********************************************************************/
8121
8122#ifdef HAVE_X_WINDOWS
8123#define HAVE_GHOSTSCRIPT 1
8124#endif /* HAVE_X_WINDOWS */
8125
8126/* The symbol `postscript' identifying images of this type.  */
8127
8128Lisp_Object Qpostscript;
8129
8130#ifdef HAVE_GHOSTSCRIPT
8131
8132static int gs_image_p P_ ((Lisp_Object object));
8133static int gs_load P_ ((struct frame *f, struct image *img));
8134static void gs_clear_image P_ ((struct frame *f, struct image *img));
8135
8136/* Keyword symbols.  */
8137
8138Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height;
8139
8140/* Indices of image specification fields in gs_format, below.  */
8141
8142enum gs_keyword_index
8143{
8144  GS_TYPE,
8145  GS_PT_WIDTH,
8146  GS_PT_HEIGHT,
8147  GS_FILE,
8148  GS_LOADER,
8149  GS_BOUNDING_BOX,
8150  GS_ASCENT,
8151  GS_MARGIN,
8152  GS_RELIEF,
8153  GS_ALGORITHM,
8154  GS_HEURISTIC_MASK,
8155  GS_MASK,
8156  GS_BACKGROUND,
8157  GS_LAST
8158};
8159
8160/* Vector of image_keyword structures describing the format
8161   of valid user-defined image specifications.  */
8162
8163static struct image_keyword gs_format[GS_LAST] =
8164{
8165  {":type",		IMAGE_SYMBOL_VALUE,			1},
8166  {":pt-width",		IMAGE_POSITIVE_INTEGER_VALUE,		1},
8167  {":pt-height",	IMAGE_POSITIVE_INTEGER_VALUE,		1},
8168  {":file",		IMAGE_STRING_VALUE,			1},
8169  {":loader",		IMAGE_FUNCTION_VALUE,			0},
8170  {":bounding-box",	IMAGE_DONT_CHECK_VALUE_TYPE,		1},
8171  {":ascent",		IMAGE_ASCENT_VALUE,			0},
8172  {":margin",		IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,	0},
8173  {":relief",		IMAGE_INTEGER_VALUE,			0},
8174  {":conversion",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
8175  {":heuristic-mask",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
8176  {":mask",		IMAGE_DONT_CHECK_VALUE_TYPE,		0},
8177  {":background",	IMAGE_STRING_OR_NIL_VALUE,		0}
8178};
8179
8180/* Structure describing the image type `ghostscript'.  */
8181
8182static struct image_type gs_type =
8183{
8184  &Qpostscript,
8185  gs_image_p,
8186  gs_load,
8187  gs_clear_image,
8188  NULL
8189};
8190
8191
8192/* Free X resources of Ghostscript image IMG which is used on frame F.  */
8193
8194static void
8195gs_clear_image (f, img)
8196     struct frame *f;
8197     struct image *img;
8198{
8199  /* IMG->data.ptr_val may contain a recorded colormap.  */
8200  xfree (img->data.ptr_val);
8201  x_clear_image (f, img);
8202}
8203
8204
8205/* Return non-zero if OBJECT is a valid Ghostscript image
8206   specification.  */
8207
8208static int
8209gs_image_p (object)
8210     Lisp_Object object;
8211{
8212  struct image_keyword fmt[GS_LAST];
8213  Lisp_Object tem;
8214  int i;
8215
8216  bcopy (gs_format, fmt, sizeof fmt);
8217
8218  if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript))
8219    return 0;
8220
8221  /* Bounding box must be a list or vector containing 4 integers.  */
8222  tem = fmt[GS_BOUNDING_BOX].value;
8223  if (CONSP (tem))
8224    {
8225      for (i = 0; i < 4; ++i, tem = XCDR (tem))
8226	if (!CONSP (tem) || !INTEGERP (XCAR (tem)))
8227	  return 0;
8228      if (!NILP (tem))
8229	return 0;
8230    }
8231  else if (VECTORP (tem))
8232    {
8233      if (XVECTOR (tem)->size != 4)
8234	return 0;
8235      for (i = 0; i < 4; ++i)
8236	if (!INTEGERP (XVECTOR (tem)->contents[i]))
8237	  return 0;
8238    }
8239  else
8240    return 0;
8241
8242  return 1;
8243}
8244
8245
8246/* Load Ghostscript image IMG for use on frame F.  Value is non-zero
8247   if successful.  */
8248
8249static int
8250gs_load (f, img)
8251     struct frame *f;
8252     struct image *img;
8253{
8254  char buffer[100];
8255  Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width;
8256  struct gcpro gcpro1, gcpro2;
8257  Lisp_Object frame;
8258  double in_width, in_height;
8259  Lisp_Object pixel_colors = Qnil;
8260
8261  /* Compute pixel size of pixmap needed from the given size in the
8262     image specification.  Sizes in the specification are in pt.  1 pt
8263     = 1/72 in, xdpi and ydpi are stored in the frame's X display
8264     info.  */
8265  pt_width = image_spec_value (img->spec, QCpt_width, NULL);
8266  in_width = XFASTINT (pt_width) / 72.0;
8267  img->width = in_width * FRAME_X_DISPLAY_INFO (f)->resx;
8268  pt_height = image_spec_value (img->spec, QCpt_height, NULL);
8269  in_height = XFASTINT (pt_height) / 72.0;
8270  img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy;
8271
8272  if (!check_image_size (f, img->width, img->height))
8273    {
8274      image_error ("Invalid image size", Qnil, Qnil);
8275      return 0;
8276    }
8277
8278  /* Create the pixmap.  */
8279  xassert (img->pixmap == NO_PIXMAP);
8280
8281  /* Only W32 version did BLOCK_INPUT here.  ++kfs */
8282  BLOCK_INPUT;
8283  img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
8284			       img->width, img->height,
8285			       DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
8286  UNBLOCK_INPUT;
8287
8288  if (!img->pixmap)
8289    {
8290      image_error ("Unable to create pixmap for `%s'", img->spec, Qnil);
8291      return 0;
8292    }
8293
8294  /* Call the loader to fill the pixmap.  It returns a process object
8295     if successful.  We do not record_unwind_protect here because
8296     other places in redisplay like calling window scroll functions
8297     don't either.  Let the Lisp loader use `unwind-protect' instead.  */
8298  GCPRO2 (window_and_pixmap_id, pixel_colors);
8299
8300  sprintf (buffer, "%lu %lu",
8301	   (unsigned long) FRAME_X_WINDOW (f),
8302	   (unsigned long) img->pixmap);
8303  window_and_pixmap_id = build_string (buffer);
8304
8305  sprintf (buffer, "%lu %lu",
8306	   FRAME_FOREGROUND_PIXEL (f),
8307	   FRAME_BACKGROUND_PIXEL (f));
8308  pixel_colors = build_string (buffer);
8309
8310  XSETFRAME (frame, f);
8311  loader = image_spec_value (img->spec, QCloader, NULL);
8312  if (NILP (loader))
8313    loader = intern ("gs-load-image");
8314
8315  img->data.lisp_val = call6 (loader, frame, img->spec,
8316			      make_number (img->width),
8317			      make_number (img->height),
8318			      window_and_pixmap_id,
8319			      pixel_colors);
8320  UNGCPRO;
8321  return PROCESSP (img->data.lisp_val);
8322}
8323
8324
8325/* Kill the Ghostscript process that was started to fill PIXMAP on
8326   frame F.  Called from XTread_socket when receiving an event
8327   telling Emacs that Ghostscript has finished drawing.  */
8328
8329void
8330x_kill_gs_process (pixmap, f)
8331     Pixmap pixmap;
8332     struct frame *f;
8333{
8334  struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
8335  int class, i;
8336  struct image *img;
8337
8338  /* Find the image containing PIXMAP.  */
8339  for (i = 0; i < c->used; ++i)
8340    if (c->images[i]->pixmap == pixmap)
8341      break;
8342
8343  /* Should someone in between have cleared the image cache, for
8344     instance, give up.  */
8345  if (i == c->used)
8346    return;
8347
8348  /* Kill the GS process.  We should have found PIXMAP in the image
8349     cache and its image should contain a process object.  */
8350  img = c->images[i];
8351  xassert (PROCESSP (img->data.lisp_val));
8352  Fkill_process (img->data.lisp_val, Qnil);
8353  img->data.lisp_val = Qnil;
8354
8355#if defined (HAVE_X_WINDOWS)
8356
8357  /* On displays with a mutable colormap, figure out the colors
8358     allocated for the image by looking at the pixels of an XImage for
8359     img->pixmap.  */
8360  class = FRAME_X_VISUAL (f)->class;
8361  if (class != StaticColor && class != StaticGray && class != TrueColor)
8362    {
8363      XImagePtr ximg;
8364
8365      BLOCK_INPUT;
8366
8367      /* Try to get an XImage for img->pixmep.  */
8368      ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
8369			0, 0, img->width, img->height, ~0, ZPixmap);
8370      if (ximg)
8371	{
8372	  int x, y;
8373
8374	  /* Initialize the color table.  */
8375	  init_color_table ();
8376
8377	  /* For each pixel of the image, look its color up in the
8378	     color table.  After having done so, the color table will
8379	     contain an entry for each color used by the image.  */
8380	  for (y = 0; y < img->height; ++y)
8381	    for (x = 0; x < img->width; ++x)
8382	      {
8383		unsigned long pixel = XGetPixel (ximg, x, y);
8384		lookup_pixel_color (f, pixel);
8385	      }
8386
8387	  /* Record colors in the image.  Free color table and XImage.  */
8388#ifdef COLOR_TABLE_SUPPORT
8389	  img->colors = colors_in_color_table (&img->ncolors);
8390	  free_color_table ();
8391#endif
8392	  XDestroyImage (ximg);
8393
8394#if 0 /* This doesn't seem to be the case.  If we free the colors
8395	 here, we get a BadAccess later in x_clear_image when
8396	 freeing the colors.  */
8397	  /* We have allocated colors once, but Ghostscript has also
8398	     allocated colors on behalf of us.  So, to get the
8399	     reference counts right, free them once.  */
8400	  if (img->ncolors)
8401	    x_free_colors (f, img->colors, img->ncolors);
8402#endif
8403	}
8404      else
8405	image_error ("Cannot get X image of `%s'; colors will not be freed",
8406		     img->spec, Qnil);
8407
8408      UNBLOCK_INPUT;
8409    }
8410#endif /* HAVE_X_WINDOWS */
8411
8412  /* Now that we have the pixmap, compute mask and transform the
8413     image if requested.  */
8414  BLOCK_INPUT;
8415  postprocess_image (f, img);
8416  UNBLOCK_INPUT;
8417}
8418
8419#endif /* HAVE_GHOSTSCRIPT */
8420
8421
8422/***********************************************************************
8423				Tests
8424 ***********************************************************************/
8425
8426#if GLYPH_DEBUG
8427
8428DEFUN ("imagep", Fimagep, Simagep, 1, 1, 0,
8429       doc: /* Value is non-nil if SPEC is a valid image specification.  */)
8430  (spec)
8431     Lisp_Object spec;
8432{
8433  return valid_image_p (spec) ? Qt : Qnil;
8434}
8435
8436
8437DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
8438  (spec)
8439     Lisp_Object spec;
8440{
8441  int id = -1;
8442
8443  if (valid_image_p (spec))
8444    id = lookup_image (SELECTED_FRAME (), spec);
8445
8446  debug_print (spec);
8447  return make_number (id);
8448}
8449
8450#endif /* GLYPH_DEBUG != 0 */
8451
8452
8453/***********************************************************************
8454			    Initialization
8455 ***********************************************************************/
8456
8457#ifdef HAVE_NTGUI
8458/* Image types that rely on external libraries are loaded dynamically
8459   if the library is available.  */
8460#define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8461  define_image_type (image_type, init_lib_fn (libraries))
8462#else
8463#define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8464  define_image_type (image_type, 1)
8465#endif /* HAVE_NTGUI */
8466
8467DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2, 2, 0,
8468       doc: /* Initialize image library implementing image type TYPE.
8469Return non-nil if TYPE is a supported image type.
8470
8471Image types pbm and xbm are prebuilt; other types are loaded here.
8472Libraries to load are specified in alist LIBRARIES (usually, the value
8473of `image-library-alist', which see).  */)
8474  (type, libraries)
8475  Lisp_Object type, libraries;
8476{
8477  Lisp_Object tested;
8478
8479  /* Don't try to reload the library.  */
8480  tested = Fassq (type, Vimage_type_cache);
8481  if (CONSP (tested))
8482    return XCDR (tested);
8483
8484#if defined (HAVE_XPM) || defined (MAC_OS)
8485  if (EQ (type, Qxpm))
8486    return CHECK_LIB_AVAILABLE (&xpm_type, init_xpm_functions, libraries);
8487#endif
8488
8489#if defined (HAVE_JPEG) || defined (MAC_OS)
8490  if (EQ (type, Qjpeg))
8491    return CHECK_LIB_AVAILABLE (&jpeg_type, init_jpeg_functions, libraries);
8492#endif
8493
8494#if defined (HAVE_TIFF) || defined (MAC_OS)
8495  if (EQ (type, Qtiff))
8496    return CHECK_LIB_AVAILABLE (&tiff_type, init_tiff_functions, libraries);
8497#endif
8498
8499#if defined (HAVE_GIF) || defined (MAC_OS)
8500  if (EQ (type, Qgif))
8501    return CHECK_LIB_AVAILABLE (&gif_type, init_gif_functions, libraries);
8502#endif
8503
8504#if defined (HAVE_PNG) || defined (MAC_OS)
8505  if (EQ (type, Qpng))
8506    return CHECK_LIB_AVAILABLE (&png_type, init_png_functions, libraries);
8507#endif
8508
8509#ifdef HAVE_GHOSTSCRIPT
8510  if (EQ (type, Qpostscript))
8511    return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries);
8512#endif
8513
8514  /* If the type is not recognized, avoid testing it ever again.  */
8515  CACHE_IMAGE_TYPE (type, Qnil);
8516  return Qnil;
8517}
8518
8519void
8520syms_of_image ()
8521{
8522  extern Lisp_Object Qrisky_local_variable;   /* Syms_of_xdisp has already run.  */
8523
8524  /* Initialize this only once, since that's what we do with Vimage_types
8525     and they are supposed to be in sync.  Initializing here gives correct
8526     operation on GNU/Linux of calling dump-emacs after loading some images.  */
8527  image_types = NULL;
8528
8529  /* Must be defined now becase we're going to update it below, while
8530     defining the supported image types.  */
8531  DEFVAR_LISP ("image-types", &Vimage_types,
8532    doc: /* List of potentially supported image types.
8533Each element of the list is a symbol for a image type, like 'jpeg or 'png.
8534To check whether it is really supported, use `image-type-available-p'.  */);
8535  Vimage_types = Qnil;
8536
8537  DEFVAR_LISP ("image-library-alist", &Vimage_library_alist,
8538    doc: /* Alist of image types vs external libraries needed to display them.
8539
8540Each element is a list (IMAGE-TYPE LIBRARY...), where the car is a symbol
8541representing a supported image type, and the rest are strings giving
8542alternate filenames for the corresponding external libraries.
8543
8544Emacs tries to load the libraries in the order they appear on the
8545list; if none is loaded, the running session of Emacs won't
8546support the image type.  Types 'pbm and 'xbm don't need to be
8547listed; they're always supported.  */);
8548  Vimage_library_alist = Qnil;
8549  Fput (intern ("image-library-alist"), Qrisky_local_variable, Qt);
8550
8551  DEFVAR_LISP ("max-image-size", &Vmax_image_size,
8552    doc: /* Maximum size of images.
8553Emacs will not load an image into memory if its pixel width or
8554pixel height exceeds this limit.
8555
8556If the value is an integer, it directly specifies the maximum
8557image height and width, measured in pixels.  If it is a floating
8558point number, it specifies the maximum image height and width
8559as a ratio to the frame height and width.  If the value is
8560non-numeric, there is no explicit limit on the size of images.  */);
8561  Vmax_image_size = make_float (MAX_IMAGE_SIZE);
8562
8563  Vimage_type_cache = Qnil;
8564  staticpro (&Vimage_type_cache);
8565
8566  Qpbm = intern ("pbm");
8567  staticpro (&Qpbm);
8568  ADD_IMAGE_TYPE(Qpbm);
8569
8570  Qxbm = intern ("xbm");
8571  staticpro (&Qxbm);
8572  ADD_IMAGE_TYPE(Qxbm);
8573
8574  define_image_type (&xbm_type, 1);
8575  define_image_type (&pbm_type, 1);
8576
8577  QCascent = intern (":ascent");
8578  staticpro (&QCascent);
8579  QCmargin = intern (":margin");
8580  staticpro (&QCmargin);
8581  QCrelief = intern (":relief");
8582  staticpro (&QCrelief);
8583  QCconversion = intern (":conversion");
8584  staticpro (&QCconversion);
8585  QCcolor_symbols = intern (":color-symbols");
8586  staticpro (&QCcolor_symbols);
8587  QCheuristic_mask = intern (":heuristic-mask");
8588  staticpro (&QCheuristic_mask);
8589  QCindex = intern (":index");
8590  staticpro (&QCindex);
8591  QCmatrix = intern (":matrix");
8592  staticpro (&QCmatrix);
8593  QCcolor_adjustment = intern (":color-adjustment");
8594  staticpro (&QCcolor_adjustment);
8595  QCmask = intern (":mask");
8596  staticpro (&QCmask);
8597
8598  Qlaplace = intern ("laplace");
8599  staticpro (&Qlaplace);
8600  Qemboss = intern ("emboss");
8601  staticpro (&Qemboss);
8602  Qedge_detection = intern ("edge-detection");
8603  staticpro (&Qedge_detection);
8604  Qheuristic = intern ("heuristic");
8605  staticpro (&Qheuristic);
8606
8607  Qpostscript = intern ("postscript");
8608  staticpro (&Qpostscript);
8609#ifdef HAVE_GHOSTSCRIPT
8610  ADD_IMAGE_TYPE(Qpostscript);
8611  QCloader = intern (":loader");
8612  staticpro (&QCloader);
8613  QCbounding_box = intern (":bounding-box");
8614  staticpro (&QCbounding_box);
8615  QCpt_width = intern (":pt-width");
8616  staticpro (&QCpt_width);
8617  QCpt_height = intern (":pt-height");
8618  staticpro (&QCpt_height);
8619#endif /* HAVE_GHOSTSCRIPT */
8620
8621#if defined (HAVE_XPM) || defined (MAC_OS)
8622  Qxpm = intern ("xpm");
8623  staticpro (&Qxpm);
8624  ADD_IMAGE_TYPE(Qxpm);
8625#endif
8626
8627#if defined (HAVE_JPEG) || defined (MAC_OS)
8628  Qjpeg = intern ("jpeg");
8629  staticpro (&Qjpeg);
8630  ADD_IMAGE_TYPE(Qjpeg);
8631#endif
8632
8633#if defined (HAVE_TIFF) || defined (MAC_OS)
8634  Qtiff = intern ("tiff");
8635  staticpro (&Qtiff);
8636  ADD_IMAGE_TYPE(Qtiff);
8637#endif
8638
8639#if defined (HAVE_GIF) || defined (MAC_OS)
8640  Qgif = intern ("gif");
8641  staticpro (&Qgif);
8642  ADD_IMAGE_TYPE(Qgif);
8643#endif
8644
8645#if defined (HAVE_PNG) || defined (MAC_OS)
8646  Qpng = intern ("png");
8647  staticpro (&Qpng);
8648  ADD_IMAGE_TYPE(Qpng);
8649#endif
8650
8651  defsubr (&Sinit_image_library);
8652  defsubr (&Sclear_image_cache);
8653  defsubr (&Simage_size);
8654  defsubr (&Simage_mask_p);
8655  defsubr (&Simage_extension_data);
8656
8657#if GLYPH_DEBUG
8658  defsubr (&Simagep);
8659  defsubr (&Slookup_image);
8660#endif
8661
8662  DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images,
8663    doc: /* Non-nil means always draw a cross over disabled images.
8664Disabled images are those having an `:conversion disabled' property.
8665A cross is always drawn on black & white displays.  */);
8666  cross_disabled_images = 0;
8667
8668  DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
8669    doc: /* List of directories to search for window system bitmap files.  */);
8670  Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS);
8671
8672  DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay,
8673    doc: /* Time after which cached images are removed from the cache.
8674When an image has not been displayed this many seconds, remove it
8675from the image cache.  Value must be an integer or nil with nil
8676meaning don't clear the cache.  */);
8677  Vimage_cache_eviction_delay = make_number (30 * 60);
8678}
8679
8680void
8681init_image ()
8682{
8683#if defined (MAC_OSX) && TARGET_API_MAC_CARBON
8684  init_image_func_pointer ();
8685#endif
8686}
8687
8688/* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9
8689   (do not change this comment) */
8690