Fix reStructuredText funky capitalization.
[emacs.git] / src / image.c
blob6701637f9519d171f261a8e583e0be8a1687a7c3
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, 2008
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 #include <config.h>
22 #include <stdio.h>
23 #include <math.h>
24 #include <ctype.h>
26 #ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
30 /* This makes the fields of a Display accessible, in Xlib header files. */
32 #define XLIB_ILLEGAL_ACCESS
34 #include "lisp.h"
35 #include "frame.h"
36 #include "window.h"
37 #include "dispextern.h"
38 #include "blockinput.h"
39 #include "systime.h"
40 #include <epaths.h>
41 #include "character.h"
42 #include "coding.h"
43 #include "termhooks.h"
44 #include "font.h"
46 #ifdef HAVE_X_WINDOWS
47 #include "xterm.h"
48 #include <sys/types.h>
49 #include <sys/stat.h>
51 #define COLOR_TABLE_SUPPORT 1
53 typedef struct x_bitmap_record Bitmap_Record;
54 #define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
55 #define NO_PIXMAP None
57 #define RGB_PIXEL_COLOR unsigned long
59 #define PIX_MASK_RETAIN 0
60 #define PIX_MASK_DRAW 1
61 #endif /* HAVE_X_WINDOWS */
64 #ifdef HAVE_NTGUI
65 #include "w32term.h"
67 /* W32_TODO : Color tables on W32. */
68 #undef COLOR_TABLE_SUPPORT
70 typedef struct w32_bitmap_record Bitmap_Record;
71 #define GET_PIXEL(ximg, x, y) GetPixel(ximg, x, y)
72 #define NO_PIXMAP 0
74 #define RGB_PIXEL_COLOR COLORREF
76 #define PIX_MASK_RETAIN 0
77 #define PIX_MASK_DRAW 1
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 */
84 #ifdef HAVE_NS
85 #include "nsterm.h"
86 #include <sys/types.h>
87 #include <sys/stat.h>
89 #undef COLOR_TABLE_SUPPORT
91 typedef struct ns_bitmap_record Bitmap_Record;
93 #define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
94 #define NO_PIXMAP 0
96 #define RGB_PIXEL_COLOR unsigned long
97 #define ZPixmap 0
99 #define PIX_MASK_RETAIN 0
100 #define PIX_MASK_DRAW 1
102 #define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO(f)->visual
103 #define x_defined_color(f, name, color_def, alloc) \
104 ns_defined_color (f, name, color_def, alloc, 0)
105 #define FRAME_X_SCREEN(f) 0
106 #define DefaultDepthOfScreen(screen) x_display_list->n_planes
107 #endif /* HAVE_NS */
110 /* Search path for bitmap files. */
112 Lisp_Object Vx_bitmap_file_path;
115 static void x_disable_image P_ ((struct frame *, struct image *));
116 static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object,
117 Lisp_Object));
119 static void init_color_table P_ ((void));
120 static unsigned long lookup_rgb_color P_ ((struct frame *f, int r, int g, int b));
121 #ifdef COLOR_TABLE_SUPPORT
122 static void free_color_table P_ ((void));
123 static unsigned long *colors_in_color_table P_ ((int *n));
124 static unsigned long lookup_pixel_color P_ ((struct frame *f, unsigned long p));
125 #endif
127 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
128 id, which is just an int that this section returns. Bitmaps are
129 reference counted so they can be shared among frames.
131 Bitmap indices are guaranteed to be > 0, so a negative number can
132 be used to indicate no bitmap.
134 If you use x_create_bitmap_from_data, then you must keep track of
135 the bitmaps yourself. That is, creating a bitmap from the same
136 data more than once will not be caught. */
138 #ifdef MAC_OS
140 static XImagePtr
141 XGetImage (display, pixmap, x, y, width, height, plane_mask, format)
142 Display *display; /* not used */
143 Pixmap pixmap;
144 int x, y; /* not used */
145 unsigned int width, height; /* not used */
146 unsigned long plane_mask; /* not used */
147 int format; /* not used */
149 #if !USE_MAC_IMAGE_IO
150 #if GLYPH_DEBUG
151 xassert (x == 0 && y == 0);
153 Rect ri, rp;
154 SetRect (&ri, 0, 0, width, height);
155 xassert (EqualRect (&ri, GetPixBounds (GetGWorldPixMap (pixmap), &rp)));
157 xassert (! (pixelsLocked & GetPixelsState (GetGWorldPixMap (pixmap))));
158 #endif
160 LockPixels (GetGWorldPixMap (pixmap));
161 #endif
163 return pixmap;
166 static void
167 XPutPixel (ximage, x, y, pixel)
168 XImagePtr ximage;
169 int x, y;
170 unsigned long pixel;
172 #if USE_MAC_IMAGE_IO
173 if (ximage->bits_per_pixel == 32)
174 ((unsigned int *)(ximage->data + y * ximage->bytes_per_line))[x] = pixel;
175 else
176 ((unsigned char *)(ximage->data + y * ximage->bytes_per_line))[x] = pixel;
177 #else
178 PixMapHandle pixmap = GetGWorldPixMap (ximage);
179 short depth = GetPixDepth (pixmap);
181 #if defined (WORDS_BIG_ENDIAN) || !USE_CG_DRAWING
182 if (depth == 32)
184 char *base_addr = GetPixBaseAddr (pixmap);
185 short row_bytes = GetPixRowBytes (pixmap);
187 ((unsigned long *) (base_addr + y * row_bytes))[x] = 0xff000000 | pixel;
189 else
190 #endif
191 if (depth == 1)
193 char *base_addr = GetPixBaseAddr (pixmap);
194 short row_bytes = GetPixRowBytes (pixmap);
196 if (pixel == PIX_MASK_DRAW)
197 base_addr[y * row_bytes + x / 8] |= (1 << 7) >> (x & 7);
198 else
199 base_addr[y * row_bytes + x / 8] &= ~((1 << 7) >> (x & 7));
201 else
203 CGrafPtr old_port;
204 GDHandle old_gdh;
205 RGBColor color;
207 GetGWorld (&old_port, &old_gdh);
208 SetGWorld (ximage, NULL);
210 color.red = RED16_FROM_ULONG (pixel);
211 color.green = GREEN16_FROM_ULONG (pixel);
212 color.blue = BLUE16_FROM_ULONG (pixel);
214 SetCPixel (x, y, &color);
216 SetGWorld (old_port, old_gdh);
218 #endif
221 static unsigned long
222 XGetPixel (ximage, x, y)
223 XImagePtr ximage;
224 int x, y;
226 #if USE_MAC_IMAGE_IO
227 if (ximage->bits_per_pixel == 32)
228 return ((unsigned int *)(ximage->data + y * ximage->bytes_per_line))[x];
229 else
230 return ((unsigned char *)(ximage->data + y * ximage->bytes_per_line))[x];
231 #else
232 PixMapHandle pixmap = GetGWorldPixMap (ximage);
233 short depth = GetPixDepth (pixmap);
235 #if defined (WORDS_BIG_ENDIAN) || !USE_CG_DRAWING
236 if (depth == 32)
238 char *base_addr = GetPixBaseAddr (pixmap);
239 short row_bytes = GetPixRowBytes (pixmap);
241 return ((unsigned long *) (base_addr + y * row_bytes))[x] & 0x00ffffff;
243 else
244 #endif
245 if (depth == 1)
247 char *base_addr = GetPixBaseAddr (pixmap);
248 short row_bytes = GetPixRowBytes (pixmap);
250 if (base_addr[y * row_bytes + x / 8] & (1 << (~x & 7)))
251 return PIX_MASK_DRAW;
252 else
253 return PIX_MASK_RETAIN;
255 else
257 CGrafPtr old_port;
258 GDHandle old_gdh;
259 RGBColor color;
261 GetGWorld (&old_port, &old_gdh);
262 SetGWorld (ximage, NULL);
264 GetCPixel (x, y, &color);
266 SetGWorld (old_port, old_gdh);
267 return RGB_TO_ULONG (color.red >> 8, color.green >> 8, color.blue >> 8);
269 #endif
272 static void
273 XDestroyImage (ximg)
274 XImagePtr ximg;
276 #if !USE_MAC_IMAGE_IO
277 UnlockPixels (GetGWorldPixMap (ximg));
278 #endif
281 #if USE_CG_DRAWING
282 #if USE_MAC_IMAGE_IO
283 void
284 mac_data_provider_release_data (info, data, size)
285 void *info;
286 const void *data;
287 size_t size;
289 xfree ((void *)data);
291 #endif
293 static CGImageRef
294 mac_create_cg_image_from_image (f, img)
295 struct frame *f;
296 struct image *img;
298 #if USE_MAC_IMAGE_IO
299 XImagePtr ximg = img->pixmap;
300 CGDataProviderRef provider;
301 CGImageRef result;
303 if (img->mask)
305 int x, y;
306 unsigned long color, alpha;
308 for (y = 0; y < ximg->height; y++)
309 for (x = 0; x < ximg->width; x++)
311 color = XGetPixel (ximg, x, y);
312 alpha = XGetPixel (img->mask, x, y);
313 XPutPixel (ximg, x, y,
314 ARGB_TO_ULONG (alpha,
315 RED_FROM_ULONG (color)
316 * alpha / PIX_MASK_DRAW,
317 GREEN_FROM_ULONG (color)
318 * alpha / PIX_MASK_DRAW,
319 BLUE_FROM_ULONG (color)
320 * alpha / PIX_MASK_DRAW));
322 xfree (img->mask->data);
323 img->mask->data = NULL;
325 BLOCK_INPUT;
326 provider = CGDataProviderCreateWithData (NULL, ximg->data,
327 ximg->bytes_per_line * ximg->height,
328 mac_data_provider_release_data);
329 ximg->data = NULL;
330 result = CGImageCreate (ximg->width, ximg->height, 8, 32,
331 ximg->bytes_per_line, mac_cg_color_space_rgb,
332 ((img->mask ? kCGImageAlphaPremultipliedFirst
333 : kCGImageAlphaNoneSkipFirst)
334 | kCGBitmapByteOrder32Host),
335 provider, NULL, 0, kCGRenderingIntentDefault);
336 CGDataProviderRelease (provider);
337 UNBLOCK_INPUT;
339 return result;
340 #else
341 Pixmap mask;
342 CGImageRef result = NULL;
344 BLOCK_INPUT;
345 if (img->mask)
346 mask = img->mask;
347 else
349 mask = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
350 img->width, img->height, 1);
351 if (mask)
353 CGrafPtr old_port;
354 GDHandle old_gdh;
355 Rect r;
357 GetGWorld (&old_port, &old_gdh);
358 SetGWorld (mask, NULL);
359 BackColor (blackColor); /* Don't mask. */
360 SetRect (&r, 0, 0, img->width, img->height);
361 EraseRect (&r);
362 SetGWorld (old_port, old_gdh);
365 if (mask)
367 CreateCGImageFromPixMaps (GetGWorldPixMap (img->pixmap),
368 GetGWorldPixMap (mask), &result);
369 if (mask != img->mask)
370 XFreePixmap (FRAME_X_DISPLAY (f), mask);
372 UNBLOCK_INPUT;
374 return result;
375 #endif
377 #endif /* USE_CG_DRAWING */
378 #endif /* MAC_OS */
380 #ifdef HAVE_NS
381 XImagePtr
382 XGetImage (Display *display, Pixmap pixmap, int x, int y,
383 unsigned int width, unsigned int height,
384 unsigned long plane_mask, int format)
386 /* TODO: not sure what this function is supposed to do.. */
387 ns_retain_object(pixmap);
388 return pixmap;
391 /* use with imgs created by ns_image_for_XPM */
392 unsigned long
393 XGetPixel (XImagePtr ximage, int x, int y)
395 return ns_get_pixel(ximage, x, y);
398 /* use with imgs created by ns_image_for_XPM; alpha set to 1;
399 pixel is assumed to be in form RGB */
400 void
401 XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel)
403 ns_put_pixel(ximage, x, y, pixel);
405 #endif /* HAVE_NS */
408 /* Functions to access the contents of a bitmap, given an id. */
411 x_bitmap_height (f, id)
412 FRAME_PTR f;
413 int id;
415 return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].height;
419 x_bitmap_width (f, id)
420 FRAME_PTR f;
421 int id;
423 return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].width;
426 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
428 x_bitmap_pixmap (f, id)
429 FRAME_PTR f;
430 int id;
432 return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
434 #endif
436 #ifdef HAVE_X_WINDOWS
438 x_bitmap_mask (f, id)
439 FRAME_PTR f;
440 int id;
442 return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].mask;
444 #endif
446 /* Allocate a new bitmap record. Returns index of new record. */
448 static int
449 x_allocate_bitmap_record (f)
450 FRAME_PTR f;
452 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
453 int i;
455 if (dpyinfo->bitmaps == NULL)
457 dpyinfo->bitmaps_size = 10;
458 dpyinfo->bitmaps
459 = (Bitmap_Record *) xmalloc (dpyinfo->bitmaps_size * sizeof (Bitmap_Record));
460 dpyinfo->bitmaps_last = 1;
461 return 1;
464 if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size)
465 return ++dpyinfo->bitmaps_last;
467 for (i = 0; i < dpyinfo->bitmaps_size; ++i)
468 if (dpyinfo->bitmaps[i].refcount == 0)
469 return i + 1;
471 dpyinfo->bitmaps_size *= 2;
472 dpyinfo->bitmaps
473 = (Bitmap_Record *) xrealloc (dpyinfo->bitmaps,
474 dpyinfo->bitmaps_size * sizeof (Bitmap_Record));
475 return ++dpyinfo->bitmaps_last;
478 /* Add one reference to the reference count of the bitmap with id ID. */
480 void
481 x_reference_bitmap (f, id)
482 FRAME_PTR f;
483 int id;
485 ++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
488 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
491 x_create_bitmap_from_data (f, bits, width, height)
492 struct frame *f;
493 char *bits;
494 unsigned int width, height;
496 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
497 int id;
499 #ifdef HAVE_X_WINDOWS
500 Pixmap bitmap;
501 bitmap = XCreateBitmapFromData (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
502 bits, width, height);
503 if (! bitmap)
504 return -1;
505 #endif /* HAVE_X_WINDOWS */
507 #ifdef HAVE_NTGUI
508 Pixmap bitmap;
509 bitmap = CreateBitmap (width, height,
510 FRAME_X_DISPLAY_INFO (XFRAME (frame))->n_planes,
511 FRAME_X_DISPLAY_INFO (XFRAME (frame))->n_cbits,
512 bits);
513 if (! bitmap)
514 return -1;
515 #endif /* HAVE_NTGUI */
517 #ifdef HAVE_NS
518 void *bitmap = ns_image_from_XBM(bits, width, height);
519 if (!bitmap)
520 return -1;
521 #endif
523 id = x_allocate_bitmap_record (f);
525 #ifdef HAVE_NS
526 dpyinfo->bitmaps[id - 1].img = bitmap;
527 dpyinfo->bitmaps[id - 1].depth = 1;
528 #endif
530 dpyinfo->bitmaps[id - 1].file = NULL;
531 dpyinfo->bitmaps[id - 1].height = height;
532 dpyinfo->bitmaps[id - 1].width = width;
533 dpyinfo->bitmaps[id - 1].refcount = 1;
535 #ifdef HAVE_X_WINDOWS
536 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
537 dpyinfo->bitmaps[id - 1].have_mask = 0;
538 dpyinfo->bitmaps[id - 1].depth = 1;
539 #endif /* HAVE_X_WINDOWS */
541 #ifdef HAVE_NTGUI
542 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
543 dpyinfo->bitmaps[id - 1].hinst = NULL;
544 dpyinfo->bitmaps[id - 1].depth = 1;
545 #endif /* HAVE_NTGUI */
547 return id;
550 /* Create bitmap from file FILE for frame F. */
553 x_create_bitmap_from_file (f, file)
554 struct frame *f;
555 Lisp_Object file;
557 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
559 #ifdef HAVE_NTGUI
560 return -1; /* W32_TODO : bitmap support */
561 #endif /* HAVE_NTGUI */
563 #ifdef HAVE_NS
564 int id;
565 void *bitmap = ns_image_from_file(file);
567 if (!bitmap)
568 return -1;
571 id = x_allocate_bitmap_record (f);
572 dpyinfo->bitmaps[id - 1].img = bitmap;
573 dpyinfo->bitmaps[id - 1].refcount = 1;
574 dpyinfo->bitmaps[id - 1].file = (char *) xmalloc (SBYTES (file) + 1);
575 dpyinfo->bitmaps[id - 1].depth = 1;
576 dpyinfo->bitmaps[id - 1].height = ns_image_width(bitmap);
577 dpyinfo->bitmaps[id - 1].width = ns_image_height(bitmap);
578 strcpy (dpyinfo->bitmaps[id - 1].file, SDATA (file));
579 return id;
580 #endif
582 #ifdef HAVE_X_WINDOWS
583 unsigned int width, height;
584 Pixmap bitmap;
585 int xhot, yhot, result, id;
586 Lisp_Object found;
587 int fd;
588 char *filename;
590 /* Look for an existing bitmap with the same name. */
591 for (id = 0; id < dpyinfo->bitmaps_last; ++id)
593 if (dpyinfo->bitmaps[id].refcount
594 && dpyinfo->bitmaps[id].file
595 && !strcmp (dpyinfo->bitmaps[id].file, (char *) SDATA (file)))
597 ++dpyinfo->bitmaps[id].refcount;
598 return id + 1;
602 /* Search bitmap-file-path for the file, if appropriate. */
603 fd = openp (Vx_bitmap_file_path, file, Qnil, &found, Qnil);
604 if (fd < 0)
605 return -1;
606 emacs_close (fd);
608 filename = (char *) SDATA (found);
610 result = XReadBitmapFile (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
611 filename, &width, &height, &bitmap, &xhot, &yhot);
612 if (result != BitmapSuccess)
613 return -1;
615 id = x_allocate_bitmap_record (f);
616 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
617 dpyinfo->bitmaps[id - 1].have_mask = 0;
618 dpyinfo->bitmaps[id - 1].refcount = 1;
619 dpyinfo->bitmaps[id - 1].file = (char *) xmalloc (SBYTES (file) + 1);
620 dpyinfo->bitmaps[id - 1].depth = 1;
621 dpyinfo->bitmaps[id - 1].height = height;
622 dpyinfo->bitmaps[id - 1].width = width;
623 strcpy (dpyinfo->bitmaps[id - 1].file, SDATA (file));
625 return id;
626 #endif /* HAVE_X_WINDOWS */
629 /* Free bitmap B. */
631 static void
632 free_bitmap_record (dpyinfo, bm)
633 Display_Info *dpyinfo;
634 Bitmap_Record *bm;
636 #ifdef HAVE_X_WINDOWS
637 XFreePixmap (dpyinfo->display, bm->pixmap);
638 if (bm->have_mask)
639 XFreePixmap (dpyinfo->display, bm->mask);
640 #endif /* HAVE_X_WINDOWS */
642 #ifdef HAVE_NTGUI
643 DeleteObject (bm->pixmap);
644 #endif /* HAVE_NTGUI */
646 #ifdef HAVE_NS
647 ns_release_object(bm->img);
648 #endif
650 if (bm->file)
652 xfree (bm->file);
653 bm->file = NULL;
657 /* Remove reference to bitmap with id number ID. */
659 void
660 x_destroy_bitmap (f, id)
661 FRAME_PTR f;
662 int id;
664 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
666 if (id > 0)
668 Bitmap_Record *bm = &dpyinfo->bitmaps[id - 1];
670 if (--bm->refcount == 0)
672 BLOCK_INPUT;
673 free_bitmap_record (dpyinfo, bm);
674 UNBLOCK_INPUT;
679 /* Free all the bitmaps for the display specified by DPYINFO. */
681 void
682 x_destroy_all_bitmaps (dpyinfo)
683 Display_Info *dpyinfo;
685 int i;
686 Bitmap_Record *bm = dpyinfo->bitmaps;
688 for (i = 0; i < dpyinfo->bitmaps_last; i++, bm++)
689 if (bm->refcount > 0)
690 free_bitmap_record (dpyinfo, bm);
692 dpyinfo->bitmaps_last = 0;
696 #ifdef HAVE_X_WINDOWS
698 /* Useful functions defined in the section
699 `Image type independent image structures' below. */
701 static unsigned long four_corners_best P_ ((XImagePtr ximg,
702 int *corners,
703 unsigned long width,
704 unsigned long height));
706 static int x_create_x_image_and_pixmap P_ ((struct frame *f, int width, int height,
707 int depth, XImagePtr *ximg,
708 Pixmap *pixmap));
710 static void x_destroy_x_image P_ ((XImagePtr ximg));
713 /* Create a mask of a bitmap. Note is this not a perfect mask.
714 It's nicer with some borders in this context */
717 x_create_bitmap_mask (f, id)
718 struct frame *f;
719 int id;
721 Pixmap pixmap, mask;
722 XImagePtr ximg, mask_img;
723 unsigned long width, height;
724 int result;
725 unsigned long bg;
726 unsigned long x, y, xp, xm, yp, ym;
727 GC gc;
729 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
731 if (!(id > 0))
732 return -1;
734 pixmap = x_bitmap_pixmap (f, id);
735 width = x_bitmap_width (f, id);
736 height = x_bitmap_height (f, id);
738 BLOCK_INPUT;
739 ximg = XGetImage (FRAME_X_DISPLAY (f), pixmap, 0, 0, width, height,
740 ~0, ZPixmap);
742 if (!ximg)
744 UNBLOCK_INPUT;
745 return -1;
748 result = x_create_x_image_and_pixmap (f, width, height, 1, &mask_img, &mask);
750 UNBLOCK_INPUT;
751 if (!result)
753 XDestroyImage (ximg);
754 return -1;
757 bg = four_corners_best (ximg, NULL, width, height);
759 for (y = 0; y < ximg->height; ++y)
761 for (x = 0; x < ximg->width; ++x)
763 xp = x != ximg->width - 1 ? x + 1 : 0;
764 xm = x != 0 ? x - 1 : ximg->width - 1;
765 yp = y != ximg->height - 1 ? y + 1 : 0;
766 ym = y != 0 ? y - 1 : ximg->height - 1;
767 if (XGetPixel (ximg, x, y) == bg
768 && XGetPixel (ximg, x, yp) == bg
769 && XGetPixel (ximg, x, ym) == bg
770 && XGetPixel (ximg, xp, y) == bg
771 && XGetPixel (ximg, xp, yp) == bg
772 && XGetPixel (ximg, xp, ym) == bg
773 && XGetPixel (ximg, xm, y) == bg
774 && XGetPixel (ximg, xm, yp) == bg
775 && XGetPixel (ximg, xm, ym) == bg)
776 XPutPixel (mask_img, x, y, 0);
777 else
778 XPutPixel (mask_img, x, y, 1);
782 xassert (interrupt_input_blocked);
783 gc = XCreateGC (FRAME_X_DISPLAY (f), mask, 0, NULL);
784 XPutImage (FRAME_X_DISPLAY (f), mask, gc, mask_img, 0, 0, 0, 0,
785 width, height);
786 XFreeGC (FRAME_X_DISPLAY (f), gc);
788 dpyinfo->bitmaps[id - 1].have_mask = 1;
789 dpyinfo->bitmaps[id - 1].mask = mask;
791 XDestroyImage (ximg);
792 x_destroy_x_image (mask_img);
794 return 0;
797 #endif /* HAVE_X_WINDOWS */
800 /***********************************************************************
801 Image types
802 ***********************************************************************/
804 /* Value is the number of elements of vector VECTOR. */
806 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
808 /* List of supported image types. Use define_image_type to add new
809 types. Use lookup_image_type to find a type for a given symbol. */
811 static struct image_type *image_types;
813 /* A list of symbols, one for each supported image type. */
815 Lisp_Object Vimage_types;
817 /* An alist of image types and libraries that implement the type. */
819 Lisp_Object Vimage_library_alist;
821 /* Cache for delayed-loading image types. */
823 static Lisp_Object Vimage_type_cache;
825 /* The symbol `xbm' which is used as the type symbol for XBM images. */
827 Lisp_Object Qxbm;
829 /* Keywords. */
831 extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile;
832 extern Lisp_Object QCdata, QCtype;
833 extern Lisp_Object Qcenter;
834 Lisp_Object QCascent, QCmargin, QCrelief, Qcount;
835 Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask;
836 Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask;
838 /* Other symbols. */
840 Lisp_Object Qlaplace, Qemboss, Qedge_detection, Qheuristic;
842 /* Time in seconds after which images should be removed from the cache
843 if not displayed. */
845 Lisp_Object Vimage_cache_eviction_delay;
847 /* Function prototypes. */
849 static Lisp_Object define_image_type P_ ((struct image_type *type, int loaded));
850 static struct image_type *lookup_image_type P_ ((Lisp_Object symbol));
851 static void image_error P_ ((char *format, Lisp_Object, Lisp_Object));
852 static void x_laplace P_ ((struct frame *, struct image *));
853 static void x_emboss P_ ((struct frame *, struct image *));
854 static int x_build_heuristic_mask P_ ((struct frame *, struct image *,
855 Lisp_Object));
857 #define CACHE_IMAGE_TYPE(type, status) \
858 do { Vimage_type_cache = Fcons (Fcons (type, status), Vimage_type_cache); } while (0)
860 #define ADD_IMAGE_TYPE(type) \
861 do { Vimage_types = Fcons (type, Vimage_types); } while (0)
863 /* Define a new image type from TYPE. This adds a copy of TYPE to
864 image_types and caches the loading status of TYPE. */
866 static Lisp_Object
867 define_image_type (type, loaded)
868 struct image_type *type;
869 int loaded;
871 Lisp_Object success;
873 if (!loaded)
874 success = Qnil;
875 else
877 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
878 The initialized data segment is read-only. */
879 struct image_type *p = (struct image_type *) xmalloc (sizeof *p);
880 bcopy (type, p, sizeof *p);
881 p->next = image_types;
882 image_types = p;
883 success = Qt;
886 CACHE_IMAGE_TYPE (*type->type, success);
887 return success;
891 /* Look up image type SYMBOL, and return a pointer to its image_type
892 structure. Value is null if SYMBOL is not a known image type. */
894 static INLINE struct image_type *
895 lookup_image_type (symbol)
896 Lisp_Object symbol;
898 struct image_type *type;
900 /* We must initialize the image-type if it hasn't been already. */
901 if (NILP (Finit_image_library (symbol, Vimage_library_alist)))
902 return 0; /* unimplemented */
904 for (type = image_types; type; type = type->next)
905 if (EQ (symbol, *type->type))
906 break;
908 return type;
912 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
913 valid image specification is a list whose car is the symbol
914 `image', and whose rest is a property list. The property list must
915 contain a value for key `:type'. That value must be the name of a
916 supported image type. The rest of the property list depends on the
917 image type. */
920 valid_image_p (object)
921 Lisp_Object object;
923 int valid_p = 0;
925 if (IMAGEP (object))
927 Lisp_Object tem;
929 for (tem = XCDR (object); CONSP (tem); tem = XCDR (tem))
930 if (EQ (XCAR (tem), QCtype))
932 tem = XCDR (tem);
933 if (CONSP (tem) && SYMBOLP (XCAR (tem)))
935 struct image_type *type;
936 type = lookup_image_type (XCAR (tem));
937 if (type)
938 valid_p = type->valid_p (object);
941 break;
945 return valid_p;
949 /* Log error message with format string FORMAT and argument ARG.
950 Signaling an error, e.g. when an image cannot be loaded, is not a
951 good idea because this would interrupt redisplay, and the error
952 message display would lead to another redisplay. This function
953 therefore simply displays a message. */
955 static void
956 image_error (format, arg1, arg2)
957 char *format;
958 Lisp_Object arg1, arg2;
960 add_to_log (format, arg1, arg2);
965 /***********************************************************************
966 Image specifications
967 ***********************************************************************/
969 enum image_value_type
971 IMAGE_DONT_CHECK_VALUE_TYPE,
972 IMAGE_STRING_VALUE,
973 IMAGE_STRING_OR_NIL_VALUE,
974 IMAGE_SYMBOL_VALUE,
975 IMAGE_POSITIVE_INTEGER_VALUE,
976 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,
977 IMAGE_NON_NEGATIVE_INTEGER_VALUE,
978 IMAGE_ASCENT_VALUE,
979 IMAGE_INTEGER_VALUE,
980 IMAGE_FUNCTION_VALUE,
981 IMAGE_NUMBER_VALUE,
982 IMAGE_BOOL_VALUE
985 /* Structure used when parsing image specifications. */
987 struct image_keyword
989 /* Name of keyword. */
990 char *name;
992 /* The type of value allowed. */
993 enum image_value_type type;
995 /* Non-zero means key must be present. */
996 int mandatory_p;
998 /* Used to recognize duplicate keywords in a property list. */
999 int count;
1001 /* The value that was found. */
1002 Lisp_Object value;
1006 static int parse_image_spec P_ ((Lisp_Object, struct image_keyword *,
1007 int, Lisp_Object));
1008 static Lisp_Object image_spec_value P_ ((Lisp_Object, Lisp_Object, int *));
1011 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
1012 has the format (image KEYWORD VALUE ...). One of the keyword/
1013 value pairs must be `:type TYPE'. KEYWORDS is a vector of
1014 image_keywords structures of size NKEYWORDS describing other
1015 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
1017 static int
1018 parse_image_spec (spec, keywords, nkeywords, type)
1019 Lisp_Object spec;
1020 struct image_keyword *keywords;
1021 int nkeywords;
1022 Lisp_Object type;
1024 int i;
1025 Lisp_Object plist;
1027 if (!IMAGEP (spec))
1028 return 0;
1030 plist = XCDR (spec);
1031 while (CONSP (plist))
1033 Lisp_Object key, value;
1035 /* First element of a pair must be a symbol. */
1036 key = XCAR (plist);
1037 plist = XCDR (plist);
1038 if (!SYMBOLP (key))
1039 return 0;
1041 /* There must follow a value. */
1042 if (!CONSP (plist))
1043 return 0;
1044 value = XCAR (plist);
1045 plist = XCDR (plist);
1047 /* Find key in KEYWORDS. Error if not found. */
1048 for (i = 0; i < nkeywords; ++i)
1049 if (strcmp (keywords[i].name, SDATA (SYMBOL_NAME (key))) == 0)
1050 break;
1052 if (i == nkeywords)
1053 continue;
1055 /* Record that we recognized the keyword. If a keywords
1056 was found more than once, it's an error. */
1057 keywords[i].value = value;
1058 ++keywords[i].count;
1060 if (keywords[i].count > 1)
1061 return 0;
1063 /* Check type of value against allowed type. */
1064 switch (keywords[i].type)
1066 case IMAGE_STRING_VALUE:
1067 if (!STRINGP (value))
1068 return 0;
1069 break;
1071 case IMAGE_STRING_OR_NIL_VALUE:
1072 if (!STRINGP (value) && !NILP (value))
1073 return 0;
1074 break;
1076 case IMAGE_SYMBOL_VALUE:
1077 if (!SYMBOLP (value))
1078 return 0;
1079 break;
1081 case IMAGE_POSITIVE_INTEGER_VALUE:
1082 if (!INTEGERP (value) || XINT (value) <= 0)
1083 return 0;
1084 break;
1086 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR:
1087 if (INTEGERP (value) && XINT (value) >= 0)
1088 break;
1089 if (CONSP (value)
1090 && INTEGERP (XCAR (value)) && INTEGERP (XCDR (value))
1091 && XINT (XCAR (value)) >= 0 && XINT (XCDR (value)) >= 0)
1092 break;
1093 return 0;
1095 case IMAGE_ASCENT_VALUE:
1096 if (SYMBOLP (value) && EQ (value, Qcenter))
1097 break;
1098 else if (INTEGERP (value)
1099 && XINT (value) >= 0
1100 && XINT (value) <= 100)
1101 break;
1102 return 0;
1104 case IMAGE_NON_NEGATIVE_INTEGER_VALUE:
1105 if (!INTEGERP (value) || XINT (value) < 0)
1106 return 0;
1107 break;
1109 case IMAGE_DONT_CHECK_VALUE_TYPE:
1110 break;
1112 case IMAGE_FUNCTION_VALUE:
1113 value = indirect_function (value);
1114 if (SUBRP (value)
1115 || COMPILEDP (value)
1116 || (CONSP (value) && EQ (XCAR (value), Qlambda)))
1117 break;
1118 return 0;
1120 case IMAGE_NUMBER_VALUE:
1121 if (!INTEGERP (value) && !FLOATP (value))
1122 return 0;
1123 break;
1125 case IMAGE_INTEGER_VALUE:
1126 if (!INTEGERP (value))
1127 return 0;
1128 break;
1130 case IMAGE_BOOL_VALUE:
1131 if (!NILP (value) && !EQ (value, Qt))
1132 return 0;
1133 break;
1135 default:
1136 abort ();
1137 break;
1140 if (EQ (key, QCtype) && !EQ (type, value))
1141 return 0;
1144 /* Check that all mandatory fields are present. */
1145 for (i = 0; i < nkeywords; ++i)
1146 if (keywords[i].mandatory_p && keywords[i].count == 0)
1147 return 0;
1149 return NILP (plist);
1153 /* Return the value of KEY in image specification SPEC. Value is nil
1154 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
1155 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
1157 static Lisp_Object
1158 image_spec_value (spec, key, found)
1159 Lisp_Object spec, key;
1160 int *found;
1162 Lisp_Object tail;
1164 xassert (valid_image_p (spec));
1166 for (tail = XCDR (spec);
1167 CONSP (tail) && CONSP (XCDR (tail));
1168 tail = XCDR (XCDR (tail)))
1170 if (EQ (XCAR (tail), key))
1172 if (found)
1173 *found = 1;
1174 return XCAR (XCDR (tail));
1178 if (found)
1179 *found = 0;
1180 return Qnil;
1184 DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0,
1185 doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
1186 PIXELS non-nil means return the size in pixels, otherwise return the
1187 size in canonical character units.
1188 FRAME is the frame on which the image will be displayed. FRAME nil
1189 or omitted means use the selected frame. */)
1190 (spec, pixels, frame)
1191 Lisp_Object spec, pixels, frame;
1193 Lisp_Object size;
1195 size = Qnil;
1196 if (valid_image_p (spec))
1198 struct frame *f = check_x_frame (frame);
1199 int id = lookup_image (f, spec);
1200 struct image *img = IMAGE_FROM_ID (f, id);
1201 int width = img->width + 2 * img->hmargin;
1202 int height = img->height + 2 * img->vmargin;
1204 if (NILP (pixels))
1205 size = Fcons (make_float ((double) width / FRAME_COLUMN_WIDTH (f)),
1206 make_float ((double) height / FRAME_LINE_HEIGHT (f)));
1207 else
1208 size = Fcons (make_number (width), make_number (height));
1210 else
1211 error ("Invalid image specification");
1213 return size;
1217 DEFUN ("image-mask-p", Fimage_mask_p, Simage_mask_p, 1, 2, 0,
1218 doc: /* Return t if image SPEC has a mask bitmap.
1219 FRAME is the frame on which the image will be displayed. FRAME nil
1220 or omitted means use the selected frame. */)
1221 (spec, frame)
1222 Lisp_Object spec, frame;
1224 Lisp_Object mask;
1226 mask = Qnil;
1227 if (valid_image_p (spec))
1229 struct frame *f = check_x_frame (frame);
1230 int id = lookup_image (f, spec);
1231 struct image *img = IMAGE_FROM_ID (f, id);
1232 if (img->mask)
1233 mask = Qt;
1235 else
1236 error ("Invalid image specification");
1238 return mask;
1241 DEFUN ("image-extension-data", Fimage_extension_data, Simage_extension_data, 1, 2, 0,
1242 doc: /* Return extension data for image SPEC.
1243 FRAME is the frame on which the image will be displayed. FRAME nil
1244 or omitted means use the selected frame. */)
1245 (spec, frame)
1246 Lisp_Object spec, frame;
1248 Lisp_Object ext;
1250 ext = Qnil;
1251 if (valid_image_p (spec))
1253 struct frame *f = check_x_frame (frame);
1254 int id = lookup_image (f, spec);
1255 struct image *img = IMAGE_FROM_ID (f, id);
1256 ext = img->data.lisp_val;
1259 return ext;
1263 /***********************************************************************
1264 Image type independent image structures
1265 ***********************************************************************/
1267 static struct image *make_image P_ ((Lisp_Object spec, unsigned hash));
1268 static void free_image P_ ((struct frame *f, struct image *img));
1269 static int check_image_size P_ ((struct frame *f, int width, int height));
1271 #define MAX_IMAGE_SIZE 6.0
1272 Lisp_Object Vmax_image_size;
1274 /* Allocate and return a new image structure for image specification
1275 SPEC. SPEC has a hash value of HASH. */
1277 static struct image *
1278 make_image (spec, hash)
1279 Lisp_Object spec;
1280 unsigned hash;
1282 struct image *img = (struct image *) xmalloc (sizeof *img);
1283 Lisp_Object file = image_spec_value (spec, QCfile, NULL);
1285 xassert (valid_image_p (spec));
1286 bzero (img, sizeof *img);
1287 img->dependencies = NILP (file) ? Qnil : list1 (file);
1288 img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL));
1289 xassert (img->type != NULL);
1290 img->spec = spec;
1291 img->data.lisp_val = Qnil;
1292 img->ascent = DEFAULT_IMAGE_ASCENT;
1293 img->hash = hash;
1294 img->corners[BOT_CORNER] = -1; /* Full image */
1295 return img;
1299 /* Free image IMG which was used on frame F, including its resources. */
1301 static void
1302 free_image (f, img)
1303 struct frame *f;
1304 struct image *img;
1306 if (img)
1308 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1310 /* Remove IMG from the hash table of its cache. */
1311 if (img->prev)
1312 img->prev->next = img->next;
1313 else
1314 c->buckets[img->hash % IMAGE_CACHE_BUCKETS_SIZE] = img->next;
1316 if (img->next)
1317 img->next->prev = img->prev;
1319 c->images[img->id] = NULL;
1321 /* Free resources, then free IMG. */
1322 img->type->free (f, img);
1323 xfree (img);
1327 /* Return 1 if the given widths and heights are valid for display;
1328 otherwise, return 0. */
1331 check_image_size (f, width, height)
1332 struct frame *f;
1333 int width;
1334 int height;
1336 int w, h;
1338 if (width <= 0 || height <= 0)
1339 return 0;
1341 if (INTEGERP (Vmax_image_size))
1342 w = h = XINT (Vmax_image_size);
1343 else if (FLOATP (Vmax_image_size))
1345 if (f != NULL)
1347 w = FRAME_PIXEL_WIDTH (f);
1348 h = FRAME_PIXEL_HEIGHT (f);
1350 else
1351 w = h = 1024; /* Arbitrary size for unknown frame. */
1352 w = (int) (XFLOAT_DATA (Vmax_image_size) * w);
1353 h = (int) (XFLOAT_DATA (Vmax_image_size) * h);
1355 else
1356 return 1;
1358 return (width <= w && height <= h);
1361 /* Prepare image IMG for display on frame F. Must be called before
1362 drawing an image. */
1364 void
1365 prepare_image_for_display (f, img)
1366 struct frame *f;
1367 struct image *img;
1369 EMACS_TIME t;
1371 /* We're about to display IMG, so set its timestamp to `now'. */
1372 EMACS_GET_TIME (t);
1373 img->timestamp = EMACS_SECS (t);
1375 /* If IMG doesn't have a pixmap yet, load it now, using the image
1376 type dependent loader function. */
1377 if (img->pixmap == NO_PIXMAP && !img->load_failed_p)
1378 img->load_failed_p = img->type->load (f, img) == 0;
1383 /* Value is the number of pixels for the ascent of image IMG when
1384 drawn in face FACE. */
1387 image_ascent (img, face, slice)
1388 struct image *img;
1389 struct face *face;
1390 struct glyph_slice *slice;
1392 int height;
1393 int ascent;
1395 if (slice->height == img->height)
1396 height = img->height + img->vmargin;
1397 else if (slice->y == 0)
1398 height = slice->height + img->vmargin;
1399 else
1400 height = slice->height;
1402 if (img->ascent == CENTERED_IMAGE_ASCENT)
1404 if (face->font)
1406 #ifdef HAVE_NTGUI
1407 /* W32 specific version. Why?. ++kfs */
1408 ascent = height / 2 - (FONT_DESCENT (face->font)
1409 - FONT_BASE (face->font)) / 2;
1410 #else
1411 /* This expression is arranged so that if the image can't be
1412 exactly centered, it will be moved slightly up. This is
1413 because a typical font is `top-heavy' (due to the presence
1414 uppercase letters), so the image placement should err towards
1415 being top-heavy too. It also just generally looks better. */
1416 ascent = (height + FONT_BASE(face->font)
1417 - FONT_DESCENT(face->font) + 1) / 2;
1418 #endif /* HAVE_NTGUI */
1420 else
1421 ascent = height / 2;
1423 else
1424 ascent = (int) (height * img->ascent / 100.0);
1426 return ascent;
1430 /* Image background colors. */
1432 /* Find the "best" corner color of a bitmap.
1433 On W32, XIMG is assumed to a device context with the bitmap selected. */
1435 static RGB_PIXEL_COLOR
1436 four_corners_best (ximg, corners, width, height)
1437 XImagePtr_or_DC ximg;
1438 int *corners;
1439 unsigned long width, height;
1441 RGB_PIXEL_COLOR corner_pixels[4], best;
1442 int i, best_count;
1444 if (corners && corners[BOT_CORNER] >= 0)
1446 /* Get the colors at the corner_pixels of ximg. */
1447 corner_pixels[0] = GET_PIXEL (ximg, corners[LEFT_CORNER], corners[TOP_CORNER]);
1448 corner_pixels[1] = GET_PIXEL (ximg, corners[RIGHT_CORNER] - 1, corners[TOP_CORNER]);
1449 corner_pixels[2] = GET_PIXEL (ximg, corners[RIGHT_CORNER] - 1, corners[BOT_CORNER] - 1);
1450 corner_pixels[3] = GET_PIXEL (ximg, corners[LEFT_CORNER], corners[BOT_CORNER] - 1);
1452 else
1454 /* Get the colors at the corner_pixels of ximg. */
1455 corner_pixels[0] = GET_PIXEL (ximg, 0, 0);
1456 corner_pixels[1] = GET_PIXEL (ximg, width - 1, 0);
1457 corner_pixels[2] = GET_PIXEL (ximg, width - 1, height - 1);
1458 corner_pixels[3] = GET_PIXEL (ximg, 0, height - 1);
1460 /* Choose the most frequently found color as background. */
1461 for (i = best_count = 0; i < 4; ++i)
1463 int j, n;
1465 for (j = n = 0; j < 4; ++j)
1466 if (corner_pixels[i] == corner_pixels[j])
1467 ++n;
1469 if (n > best_count)
1470 best = corner_pixels[i], best_count = n;
1473 return best;
1476 /* Portability macros */
1478 #ifdef HAVE_NTGUI
1480 #define Destroy_Image(img_dc, prev) \
1481 do { SelectObject (img_dc, prev); DeleteDC (img_dc); } while (0)
1483 #define Free_Pixmap(display, pixmap) \
1484 DeleteObject (pixmap)
1486 #elif defined (HAVE_NS)
1488 #define Destroy_Image(ximg, dummy) \
1489 ns_release_object(ximg)
1491 #define Free_Pixmap(display, pixmap) \
1492 ns_release_object(pixmap)
1494 #else
1496 #define Destroy_Image(ximg, dummy) \
1497 XDestroyImage (ximg)
1499 #define Free_Pixmap(display, pixmap) \
1500 XFreePixmap (display, pixmap)
1502 #endif /* !HAVE_NTGUI && !HAVE_NS */
1505 /* Return the `background' field of IMG. If IMG doesn't have one yet,
1506 it is guessed heuristically. If non-zero, XIMG is an existing
1507 XImage object (or device context with the image selected on W32) to
1508 use for the heuristic. */
1510 RGB_PIXEL_COLOR
1511 image_background (img, f, ximg)
1512 struct image *img;
1513 struct frame *f;
1514 XImagePtr_or_DC ximg;
1516 if (! img->background_valid)
1517 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1519 int free_ximg = !ximg;
1520 #ifdef HAVE_NTGUI
1521 HGDIOBJ prev;
1522 #endif /* HAVE_NTGUI */
1524 if (free_ximg)
1526 #ifndef HAVE_NTGUI
1527 ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
1528 0, 0, img->width, img->height, ~0, ZPixmap);
1529 #else
1530 HDC frame_dc = get_frame_dc (f);
1531 ximg = CreateCompatibleDC (frame_dc);
1532 release_frame_dc (f, frame_dc);
1533 prev = SelectObject (ximg, img->pixmap);
1534 #endif /* !HAVE_NTGUI */
1537 img->background = four_corners_best (ximg, img->corners, img->width, img->height);
1539 if (free_ximg)
1540 Destroy_Image (ximg, prev);
1542 img->background_valid = 1;
1545 return img->background;
1548 /* Return the `background_transparent' field of IMG. If IMG doesn't
1549 have one yet, it is guessed heuristically. If non-zero, MASK is an
1550 existing XImage object to use for the heuristic. */
1553 image_background_transparent (img, f, mask)
1554 struct image *img;
1555 struct frame *f;
1556 XImagePtr_or_DC mask;
1558 if (! img->background_transparent_valid)
1559 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1561 if (img->mask)
1563 int free_mask = !mask;
1564 #ifdef HAVE_NTGUI
1565 HGDIOBJ prev;
1566 #endif /* HAVE_NTGUI */
1568 if (free_mask)
1570 #ifndef HAVE_NTGUI
1571 mask = XGetImage (FRAME_X_DISPLAY (f), img->mask,
1572 0, 0, img->width, img->height, ~0, ZPixmap);
1573 #else
1574 HDC frame_dc = get_frame_dc (f);
1575 mask = CreateCompatibleDC (frame_dc);
1576 release_frame_dc (f, frame_dc);
1577 prev = SelectObject (mask, img->mask);
1578 #endif /* HAVE_NTGUI */
1581 img->background_transparent
1582 = (four_corners_best (mask, img->corners, img->width, img->height) == PIX_MASK_RETAIN);
1584 if (free_mask)
1585 Destroy_Image (mask, prev);
1587 else
1588 img->background_transparent = 0;
1590 img->background_transparent_valid = 1;
1593 return img->background_transparent;
1597 /***********************************************************************
1598 Helper functions for X image types
1599 ***********************************************************************/
1601 static void x_clear_image_1 P_ ((struct frame *, struct image *, int,
1602 int, int));
1603 static void x_clear_image P_ ((struct frame *f, struct image *img));
1604 static unsigned long x_alloc_image_color P_ ((struct frame *f,
1605 struct image *img,
1606 Lisp_Object color_name,
1607 unsigned long dflt));
1610 /* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
1611 free the pixmap if any. MASK_P non-zero means clear the mask
1612 pixmap if any. COLORS_P non-zero means free colors allocated for
1613 the image, if any. */
1615 static void
1616 x_clear_image_1 (f, img, pixmap_p, mask_p, colors_p)
1617 struct frame *f;
1618 struct image *img;
1619 int pixmap_p, mask_p, colors_p;
1621 if (pixmap_p && img->pixmap)
1623 Free_Pixmap (FRAME_X_DISPLAY (f), img->pixmap);
1624 img->pixmap = NO_PIXMAP;
1625 /* NOTE (HAVE_NS): background color is NOT an indexed color! */
1626 img->background_valid = 0;
1629 if (mask_p && img->mask)
1631 Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
1632 img->mask = NO_PIXMAP;
1633 img->background_transparent_valid = 0;
1636 if (colors_p && img->ncolors)
1638 /* W32_TODO: color table support. */
1639 #ifdef HAVE_X_WINDOWS
1640 x_free_colors (f, img->colors, img->ncolors);
1641 #endif /* HAVE_X_WINDOWS */
1642 xfree (img->colors);
1643 img->colors = NULL;
1644 img->ncolors = 0;
1649 /* Free X resources of image IMG which is used on frame F. */
1651 static void
1652 x_clear_image (f, img)
1653 struct frame *f;
1654 struct image *img;
1656 BLOCK_INPUT;
1657 x_clear_image_1 (f, img, 1, 1, 1);
1658 UNBLOCK_INPUT;
1662 /* Allocate color COLOR_NAME for image IMG on frame F. If color
1663 cannot be allocated, use DFLT. Add a newly allocated color to
1664 IMG->colors, so that it can be freed again. Value is the pixel
1665 color. */
1667 static unsigned long
1668 x_alloc_image_color (f, img, color_name, dflt)
1669 struct frame *f;
1670 struct image *img;
1671 Lisp_Object color_name;
1672 unsigned long dflt;
1674 XColor color;
1675 unsigned long result;
1677 xassert (STRINGP (color_name));
1679 if (x_defined_color (f, SDATA (color_name), &color, 1))
1681 /* This isn't called frequently so we get away with simply
1682 reallocating the color vector to the needed size, here. */
1683 ++img->ncolors;
1684 img->colors =
1685 (unsigned long *) xrealloc (img->colors,
1686 img->ncolors * sizeof *img->colors);
1687 img->colors[img->ncolors - 1] = color.pixel;
1688 result = color.pixel;
1690 else
1691 result = dflt;
1693 return result;
1698 /***********************************************************************
1699 Image Cache
1700 ***********************************************************************/
1702 static struct image *search_image_cache P_ ((struct frame *, Lisp_Object, unsigned));
1703 static void cache_image P_ ((struct frame *f, struct image *img));
1704 static void postprocess_image P_ ((struct frame *, struct image *));
1706 /* Return a new, initialized image cache that is allocated from the
1707 heap. Call free_image_cache to free an image cache. */
1709 struct image_cache *
1710 make_image_cache ()
1712 struct image_cache *c = (struct image_cache *) xmalloc (sizeof *c);
1713 int size;
1715 bzero (c, sizeof *c);
1716 c->size = 50;
1717 c->images = (struct image **) xmalloc (c->size * sizeof *c->images);
1718 size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
1719 c->buckets = (struct image **) xmalloc (size);
1720 bzero (c->buckets, size);
1721 return c;
1725 /* Find an image matching SPEC in the cache, and return it. If no
1726 image is found, return NULL. */
1727 static struct image *
1728 search_image_cache (f, spec, hash)
1729 struct frame *f;
1730 Lisp_Object spec;
1731 unsigned hash;
1733 struct image *img;
1734 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1735 int i = hash % IMAGE_CACHE_BUCKETS_SIZE;
1737 if (!c) return NULL;
1739 /* If the image spec does not specify a background color, the cached
1740 image must have the same background color as the current frame.
1741 The foreground color must also match, for the sake of monochrome
1742 images.
1744 In fact, we could ignore the foreground color matching condition
1745 for color images, or if the image spec specifies :foreground;
1746 similarly we could ignore the background color matching condition
1747 for formats that don't use transparency (such as jpeg), or if the
1748 image spec specifies :background. However, the extra memory
1749 usage is probably negligible in practice, so we don't bother. */
1751 for (img = c->buckets[i]; img; img = img->next)
1752 if (img->hash == hash
1753 && !NILP (Fequal (img->spec, spec))
1754 && img->frame_foreground == FRAME_FOREGROUND_PIXEL (f)
1755 && img->frame_background == FRAME_BACKGROUND_PIXEL (f))
1756 break;
1757 return img;
1761 /* Search frame F for an image with spec SPEC, and free it. */
1763 static void
1764 uncache_image (f, spec)
1765 struct frame *f;
1766 Lisp_Object spec;
1768 struct image *img = search_image_cache (f, spec, sxhash (spec, 0));
1769 if (img)
1770 free_image (f, img);
1774 /* Free image cache of frame F. Be aware that X frames share images
1775 caches. */
1777 void
1778 free_image_cache (f)
1779 struct frame *f;
1781 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1782 if (c)
1784 int i;
1786 /* Cache should not be referenced by any frame when freed. */
1787 xassert (c->refcount == 0);
1789 for (i = 0; i < c->used; ++i)
1790 free_image (f, c->images[i]);
1791 xfree (c->images);
1792 xfree (c->buckets);
1793 xfree (c);
1794 FRAME_IMAGE_CACHE (f) = NULL;
1799 /* Clear image cache of frame F. FILTER=t means free all images.
1800 FILTER=nil means clear only images that haven't been
1801 displayed for some time.
1802 Else, only free the images which have FILTER in their `dependencies'.
1803 Should be called from time to time to reduce the number of loaded images.
1804 If image-cache-eviction-delay is non-nil, this frees images in the cache
1805 which weren't displayed for at least that many seconds. */
1807 void
1808 clear_image_cache (struct frame *f, Lisp_Object filter)
1810 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1812 if (c && (!NILP (filter) || INTEGERP (Vimage_cache_eviction_delay)))
1814 EMACS_TIME t;
1815 unsigned long old;
1816 int i, nfreed;
1818 EMACS_GET_TIME (t);
1819 old = EMACS_SECS (t) - XFASTINT (Vimage_cache_eviction_delay);
1821 /* Block input so that we won't be interrupted by a SIGIO
1822 while being in an inconsistent state. */
1823 BLOCK_INPUT;
1825 for (i = nfreed = 0; i < c->used; ++i)
1827 struct image *img = c->images[i];
1828 if (img != NULL
1829 && (NILP (filter) ? img->timestamp < old
1830 : (EQ (Qt, filter)
1831 || !NILP (Fmember (filter, img->dependencies)))))
1833 free_image (f, img);
1834 ++nfreed;
1838 /* We may be clearing the image cache because, for example,
1839 Emacs was iconified for a longer period of time. In that
1840 case, current matrices may still contain references to
1841 images freed above. So, clear these matrices. */
1842 if (nfreed)
1844 Lisp_Object tail, frame;
1846 FOR_EACH_FRAME (tail, frame)
1848 struct frame *f = XFRAME (frame);
1849 if (FRAME_IMAGE_CACHE (f) == c)
1850 clear_current_matrices (f);
1853 ++windows_or_buffers_changed;
1856 UNBLOCK_INPUT;
1860 void
1861 clear_image_caches (Lisp_Object filter)
1863 /* FIXME: We want to do
1864 * struct terminal *t;
1865 * for (t = terminal_list; t; t = t->next_terminal)
1866 * clear_image_cache (t, filter); */
1867 Lisp_Object tail, frame;
1868 FOR_EACH_FRAME (tail, frame)
1869 if (FRAME_WINDOW_P (XFRAME (frame)))
1870 clear_image_cache (XFRAME (frame), filter);
1873 DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache,
1874 0, 1, 0,
1875 doc: /* Clear the image cache.
1876 FILTER nil or a frame means clear all images in the selected frame.
1877 FILTER t means clear the image caches of all frames.
1878 Anything else, means only clear those images which refer to FILTER,
1879 which is then usually a filename. */)
1880 (filter)
1881 Lisp_Object filter;
1883 if (!(EQ (filter, Qnil) || FRAMEP (filter)))
1884 clear_image_caches (filter);
1885 else
1886 clear_image_cache (check_x_frame (filter), Qt);
1888 return Qnil;
1892 DEFUN ("image-refresh", Fimage_refresh, Simage_refresh,
1893 1, 2, 0,
1894 doc: /* Refresh the image with specification SPEC on frame FRAME.
1895 If SPEC specifies an image file, the displayed image is updated with
1896 the current contents of that file.
1897 FRAME nil or omitted means use the selected frame.
1898 FRAME t means refresh the image on all frames. */)
1899 (spec, frame)
1900 Lisp_Object spec, frame;
1902 if (!valid_image_p (spec))
1903 error ("Invalid image specification");
1905 if (EQ (frame, Qt))
1907 Lisp_Object tail;
1908 FOR_EACH_FRAME (tail, frame)
1910 struct frame *f = XFRAME (frame);
1911 if (FRAME_WINDOW_P (f))
1912 uncache_image (f, spec);
1915 else
1916 uncache_image (check_x_frame (frame), spec);
1918 return Qnil;
1922 /* Compute masks and transform image IMG on frame F, as specified
1923 by the image's specification, */
1925 static void
1926 postprocess_image (f, img)
1927 struct frame *f;
1928 struct image *img;
1930 /* Manipulation of the image's mask. */
1931 if (img->pixmap)
1933 Lisp_Object conversion, spec;
1934 Lisp_Object mask;
1936 spec = img->spec;
1938 /* `:heuristic-mask t'
1939 `:mask heuristic'
1940 means build a mask heuristically.
1941 `:heuristic-mask (R G B)'
1942 `:mask (heuristic (R G B))'
1943 means build a mask from color (R G B) in the
1944 image.
1945 `:mask nil'
1946 means remove a mask, if any. */
1948 mask = image_spec_value (spec, QCheuristic_mask, NULL);
1949 if (!NILP (mask))
1950 x_build_heuristic_mask (f, img, mask);
1951 else
1953 int found_p;
1955 mask = image_spec_value (spec, QCmask, &found_p);
1957 if (EQ (mask, Qheuristic))
1958 x_build_heuristic_mask (f, img, Qt);
1959 else if (CONSP (mask)
1960 && EQ (XCAR (mask), Qheuristic))
1962 if (CONSP (XCDR (mask)))
1963 x_build_heuristic_mask (f, img, XCAR (XCDR (mask)));
1964 else
1965 x_build_heuristic_mask (f, img, XCDR (mask));
1967 else if (NILP (mask) && found_p && img->mask)
1969 Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
1970 img->mask = NO_PIXMAP;
1975 /* Should we apply an image transformation algorithm? */
1976 conversion = image_spec_value (spec, QCconversion, NULL);
1977 if (EQ (conversion, Qdisabled))
1978 x_disable_image (f, img);
1979 else if (EQ (conversion, Qlaplace))
1980 x_laplace (f, img);
1981 else if (EQ (conversion, Qemboss))
1982 x_emboss (f, img);
1983 else if (CONSP (conversion)
1984 && EQ (XCAR (conversion), Qedge_detection))
1986 Lisp_Object tem;
1987 tem = XCDR (conversion);
1988 if (CONSP (tem))
1989 x_edge_detection (f, img,
1990 Fplist_get (tem, QCmatrix),
1991 Fplist_get (tem, QCcolor_adjustment));
1997 /* Return the id of image with Lisp specification SPEC on frame F.
1998 SPEC must be a valid Lisp image specification (see valid_image_p). */
2001 lookup_image (f, spec)
2002 struct frame *f;
2003 Lisp_Object spec;
2005 struct image_cache *c;
2006 struct image *img;
2007 unsigned hash;
2008 struct gcpro gcpro1;
2009 EMACS_TIME now;
2011 /* F must be a window-system frame, and SPEC must be a valid image
2012 specification. */
2013 xassert (FRAME_WINDOW_P (f));
2014 xassert (valid_image_p (spec));
2016 c = FRAME_IMAGE_CACHE (f);
2018 GCPRO1 (spec);
2020 /* Look up SPEC in the hash table of the image cache. */
2021 hash = sxhash (spec, 0);
2022 img = search_image_cache (f, spec, hash);
2023 if (img && img->load_failed_p)
2025 free_image (f, img);
2026 img = NULL;
2029 /* If not found, create a new image and cache it. */
2030 if (img == NULL)
2032 extern Lisp_Object Qpostscript;
2034 BLOCK_INPUT;
2035 img = make_image (spec, hash);
2036 cache_image (f, img);
2037 img->load_failed_p = img->type->load (f, img) == 0;
2038 img->frame_foreground = FRAME_FOREGROUND_PIXEL (f);
2039 img->frame_background = FRAME_BACKGROUND_PIXEL (f);
2041 /* If we can't load the image, and we don't have a width and
2042 height, use some arbitrary width and height so that we can
2043 draw a rectangle for it. */
2044 if (img->load_failed_p)
2046 Lisp_Object value;
2048 value = image_spec_value (spec, QCwidth, NULL);
2049 img->width = (INTEGERP (value)
2050 ? XFASTINT (value) : DEFAULT_IMAGE_WIDTH);
2051 value = image_spec_value (spec, QCheight, NULL);
2052 img->height = (INTEGERP (value)
2053 ? XFASTINT (value) : DEFAULT_IMAGE_HEIGHT);
2055 else
2057 /* Handle image type independent image attributes
2058 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
2059 `:background COLOR'. */
2060 Lisp_Object ascent, margin, relief, bg;
2062 ascent = image_spec_value (spec, QCascent, NULL);
2063 if (INTEGERP (ascent))
2064 img->ascent = XFASTINT (ascent);
2065 else if (EQ (ascent, Qcenter))
2066 img->ascent = CENTERED_IMAGE_ASCENT;
2068 margin = image_spec_value (spec, QCmargin, NULL);
2069 if (INTEGERP (margin) && XINT (margin) >= 0)
2070 img->vmargin = img->hmargin = XFASTINT (margin);
2071 else if (CONSP (margin) && INTEGERP (XCAR (margin))
2072 && INTEGERP (XCDR (margin)))
2074 if (XINT (XCAR (margin)) > 0)
2075 img->hmargin = XFASTINT (XCAR (margin));
2076 if (XINT (XCDR (margin)) > 0)
2077 img->vmargin = XFASTINT (XCDR (margin));
2080 relief = image_spec_value (spec, QCrelief, NULL);
2081 if (INTEGERP (relief))
2083 img->relief = XINT (relief);
2084 img->hmargin += eabs (img->relief);
2085 img->vmargin += eabs (img->relief);
2088 if (! img->background_valid)
2090 bg = image_spec_value (img->spec, QCbackground, NULL);
2091 if (!NILP (bg))
2093 img->background
2094 = x_alloc_image_color (f, img, bg,
2095 FRAME_BACKGROUND_PIXEL (f));
2096 img->background_valid = 1;
2100 /* Do image transformations and compute masks, unless we
2101 don't have the image yet. */
2102 if (!EQ (*img->type->type, Qpostscript))
2103 postprocess_image (f, img);
2106 UNBLOCK_INPUT;
2109 /* We're using IMG, so set its timestamp to `now'. */
2110 EMACS_GET_TIME (now);
2111 img->timestamp = EMACS_SECS (now);
2113 UNGCPRO;
2115 /* Value is the image id. */
2116 return img->id;
2120 /* Cache image IMG in the image cache of frame F. */
2122 static void
2123 cache_image (f, img)
2124 struct frame *f;
2125 struct image *img;
2127 struct image_cache *c = FRAME_IMAGE_CACHE (f);
2128 int i;
2130 /* Find a free slot in c->images. */
2131 for (i = 0; i < c->used; ++i)
2132 if (c->images[i] == NULL)
2133 break;
2135 /* If no free slot found, maybe enlarge c->images. */
2136 if (i == c->used && c->used == c->size)
2138 c->size *= 2;
2139 c->images = (struct image **) xrealloc (c->images,
2140 c->size * sizeof *c->images);
2143 /* Add IMG to c->images, and assign IMG an id. */
2144 c->images[i] = img;
2145 img->id = i;
2146 if (i == c->used)
2147 ++c->used;
2149 /* Add IMG to the cache's hash table. */
2150 i = img->hash % IMAGE_CACHE_BUCKETS_SIZE;
2151 img->next = c->buckets[i];
2152 if (img->next)
2153 img->next->prev = img;
2154 img->prev = NULL;
2155 c->buckets[i] = img;
2159 /* Call FN on every image in the image cache of frame F. Used to mark
2160 Lisp Objects in the image cache. */
2162 /* Mark Lisp objects in image IMG. */
2164 static void
2165 mark_image (img)
2166 struct image *img;
2168 mark_object (img->spec);
2169 mark_object (img->dependencies);
2171 if (!NILP (img->data.lisp_val))
2172 mark_object (img->data.lisp_val);
2176 void
2177 mark_image_cache (struct image_cache *c)
2179 if (c)
2181 int i;
2182 for (i = 0; i < c->used; ++i)
2183 if (c->images[i])
2184 mark_image (c->images[i]);
2190 /***********************************************************************
2191 X / NS / W32 support code
2192 ***********************************************************************/
2194 #ifdef HAVE_NTGUI
2196 /* Macro for defining functions that will be loaded from image DLLs. */
2197 #define DEF_IMGLIB_FN(func) int (FAR CDECL *fn_##func)()
2199 /* Macro for loading those image functions from the library. */
2200 #define LOAD_IMGLIB_FN(lib,func) { \
2201 fn_##func = (void *) GetProcAddress (lib, #func); \
2202 if (!fn_##func) return 0; \
2205 /* Load a DLL implementing an image type.
2206 The `image-library-alist' variable associates a symbol,
2207 identifying an image type, to a list of possible filenames.
2208 The function returns NULL if no library could be loaded for
2209 the given image type, or if the library was previously loaded;
2210 else the handle of the DLL. */
2211 static HMODULE
2212 w32_delayed_load (Lisp_Object libraries, Lisp_Object type)
2214 HMODULE library = NULL;
2216 if (CONSP (libraries) && NILP (Fassq (type, Vimage_type_cache)))
2218 Lisp_Object dlls = Fassq (type, libraries);
2220 if (CONSP (dlls))
2221 for (dlls = XCDR (dlls); CONSP (dlls); dlls = XCDR (dlls))
2223 CHECK_STRING_CAR (dlls);
2224 if (library = LoadLibrary (SDATA (XCAR (dlls))))
2225 break;
2229 return library;
2232 #endif /* HAVE_NTGUI */
2234 static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int,
2235 XImagePtr *, Pixmap *));
2236 static void x_destroy_x_image P_ ((XImagePtr));
2237 static void x_put_x_image P_ ((struct frame *, XImagePtr, Pixmap, int, int));
2240 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
2241 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
2242 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
2243 via xmalloc. Print error messages via image_error if an error
2244 occurs. Value is non-zero if successful.
2246 On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
2247 should indicate the bit depth of the image. */
2249 static int
2250 x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap)
2251 struct frame *f;
2252 int width, height, depth;
2253 XImagePtr *ximg;
2254 Pixmap *pixmap;
2256 #ifdef HAVE_X_WINDOWS
2257 Display *display = FRAME_X_DISPLAY (f);
2258 Window window = FRAME_X_WINDOW (f);
2259 Screen *screen = FRAME_X_SCREEN (f);
2261 xassert (interrupt_input_blocked);
2263 if (depth <= 0)
2264 depth = DefaultDepthOfScreen (screen);
2265 *ximg = XCreateImage (display, DefaultVisualOfScreen (screen),
2266 depth, ZPixmap, 0, NULL, width, height,
2267 depth > 16 ? 32 : depth > 8 ? 16 : 8, 0);
2268 if (*ximg == NULL)
2270 image_error ("Unable to allocate X image", Qnil, Qnil);
2271 return 0;
2274 /* Allocate image raster. */
2275 (*ximg)->data = (char *) xmalloc ((*ximg)->bytes_per_line * height);
2277 /* Allocate a pixmap of the same size. */
2278 *pixmap = XCreatePixmap (display, window, width, height, depth);
2279 if (*pixmap == NO_PIXMAP)
2281 x_destroy_x_image (*ximg);
2282 *ximg = NULL;
2283 image_error ("Unable to create X pixmap", Qnil, Qnil);
2284 return 0;
2287 return 1;
2288 #endif /* HAVE_X_WINDOWS */
2290 #ifdef HAVE_NTGUI
2292 BITMAPINFOHEADER *header;
2293 HDC hdc;
2294 int scanline_width_bits;
2295 int remainder;
2296 int palette_colors = 0;
2298 if (depth == 0)
2299 depth = 24;
2301 if (depth != 1 && depth != 4 && depth != 8
2302 && depth != 16 && depth != 24 && depth != 32)
2304 image_error ("Invalid image bit depth specified", Qnil, Qnil);
2305 return 0;
2308 scanline_width_bits = width * depth;
2309 remainder = scanline_width_bits % 32;
2311 if (remainder)
2312 scanline_width_bits += 32 - remainder;
2314 /* Bitmaps with a depth less than 16 need a palette. */
2315 /* BITMAPINFO structure already contains the first RGBQUAD. */
2316 if (depth < 16)
2317 palette_colors = 1 << depth - 1;
2319 *ximg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD));
2320 if (*ximg == NULL)
2322 image_error ("Unable to allocate memory for XImage", Qnil, Qnil);
2323 return 0;
2326 header = &((*ximg)->info.bmiHeader);
2327 bzero (&((*ximg)->info), sizeof (BITMAPINFO));
2328 header->biSize = sizeof (*header);
2329 header->biWidth = width;
2330 header->biHeight = -height; /* negative indicates a top-down bitmap. */
2331 header->biPlanes = 1;
2332 header->biBitCount = depth;
2333 header->biCompression = BI_RGB;
2334 header->biClrUsed = palette_colors;
2336 /* TODO: fill in palette. */
2337 if (depth == 1)
2339 (*ximg)->info.bmiColors[0].rgbBlue = 0;
2340 (*ximg)->info.bmiColors[0].rgbGreen = 0;
2341 (*ximg)->info.bmiColors[0].rgbRed = 0;
2342 (*ximg)->info.bmiColors[0].rgbReserved = 0;
2343 (*ximg)->info.bmiColors[1].rgbBlue = 255;
2344 (*ximg)->info.bmiColors[1].rgbGreen = 255;
2345 (*ximg)->info.bmiColors[1].rgbRed = 255;
2346 (*ximg)->info.bmiColors[1].rgbReserved = 0;
2349 hdc = get_frame_dc (f);
2351 /* Create a DIBSection and raster array for the bitmap,
2352 and store its handle in *pixmap. */
2353 *pixmap = CreateDIBSection (hdc, &((*ximg)->info),
2354 (depth < 16) ? DIB_PAL_COLORS : DIB_RGB_COLORS,
2355 /* casting avoids a GCC warning */
2356 (void **)&((*ximg)->data), NULL, 0);
2358 /* Realize display palette and garbage all frames. */
2359 release_frame_dc (f, hdc);
2361 if (*pixmap == NULL)
2363 DWORD err = GetLastError ();
2364 Lisp_Object errcode;
2365 /* All system errors are < 10000, so the following is safe. */
2366 XSETINT (errcode, (int) err);
2367 image_error ("Unable to create bitmap, error code %d", errcode, Qnil);
2368 x_destroy_x_image (*ximg);
2369 return 0;
2372 return 1;
2374 #endif /* HAVE_NTGUI */
2376 #ifdef HAVE_NS
2377 *pixmap = ns_image_for_XPM(width, height, depth);
2378 if (*pixmap == 0)
2380 *ximg = NULL;
2381 image_error ("Unable to allocate NSImage for XPM pixmap", Qnil, Qnil);
2382 return 0;
2384 *ximg = *pixmap;
2385 return 1;
2386 #endif
2390 /* Destroy XImage XIMG. Free XIMG->data. */
2392 static void
2393 x_destroy_x_image (ximg)
2394 XImagePtr ximg;
2396 xassert (interrupt_input_blocked);
2397 if (ximg)
2399 #ifdef HAVE_X_WINDOWS
2400 xfree (ximg->data);
2401 ximg->data = NULL;
2402 XDestroyImage (ximg);
2403 #endif /* HAVE_X_WINDOWS */
2404 #ifdef HAVE_NTGUI
2405 /* Data will be freed by DestroyObject. */
2406 ximg->data = NULL;
2407 xfree (ximg);
2408 #endif /* HAVE_NTGUI */
2409 #ifdef HAVE_NS
2410 ns_release_object(ximg);
2411 #endif /* HAVE_NS */
2416 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
2417 are width and height of both the image and pixmap. */
2419 static void
2420 x_put_x_image (f, ximg, pixmap, width, height)
2421 struct frame *f;
2422 XImagePtr ximg;
2423 Pixmap pixmap;
2424 int width, height;
2426 #ifdef HAVE_X_WINDOWS
2427 GC gc;
2429 xassert (interrupt_input_blocked);
2430 gc = XCreateGC (FRAME_X_DISPLAY (f), pixmap, 0, NULL);
2431 XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, ximg, 0, 0, 0, 0, width, height);
2432 XFreeGC (FRAME_X_DISPLAY (f), gc);
2433 #endif /* HAVE_X_WINDOWS */
2435 #ifdef HAVE_NTGUI
2436 #if 0 /* I don't think this is necessary looking at where it is used. */
2437 HDC hdc = get_frame_dc (f);
2438 SetDIBits (hdc, pixmap, 0, height, ximg->data, &(ximg->info), DIB_RGB_COLORS);
2439 release_frame_dc (f, hdc);
2440 #endif
2441 #endif /* HAVE_NTGUI */
2443 #ifdef HAVE_NS
2444 xassert (ximg == pixmap);
2445 ns_retain_object(ximg);
2446 #endif
2450 /***********************************************************************
2451 File Handling
2452 ***********************************************************************/
2454 static unsigned char *slurp_file P_ ((char *, int *));
2457 /* Find image file FILE. Look in data-directory/images, then
2458 x-bitmap-file-path. Value is the encoded full name of the file
2459 found, or nil if not found. */
2461 Lisp_Object
2462 x_find_image_file (file)
2463 Lisp_Object file;
2465 Lisp_Object file_found, search_path;
2466 struct gcpro gcpro1, gcpro2;
2467 int fd;
2469 file_found = Qnil;
2470 /* TODO I think this should use something like image-load-path
2471 instead. Unfortunately, that can contain non-string elements. */
2472 search_path = Fcons (Fexpand_file_name (build_string ("images"),
2473 Vdata_directory),
2474 Vx_bitmap_file_path);
2475 GCPRO2 (file_found, search_path);
2477 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
2478 fd = openp (search_path, file, Qnil, &file_found, Qnil);
2480 if (fd == -1)
2481 file_found = Qnil;
2482 else
2484 file_found = ENCODE_FILE (file_found);
2485 close (fd);
2488 UNGCPRO;
2489 return file_found;
2493 /* Read FILE into memory. Value is a pointer to a buffer allocated
2494 with xmalloc holding FILE's contents. Value is null if an error
2495 occurred. *SIZE is set to the size of the file. */
2497 static unsigned char *
2498 slurp_file (file, size)
2499 char *file;
2500 int *size;
2502 FILE *fp = NULL;
2503 unsigned char *buf = NULL;
2504 struct stat st;
2506 if (stat (file, &st) == 0
2507 && (fp = fopen (file, "rb")) != NULL
2508 && (buf = (unsigned char *) xmalloc (st.st_size),
2509 fread (buf, 1, st.st_size, fp) == st.st_size))
2511 *size = st.st_size;
2512 fclose (fp);
2514 else
2516 if (fp)
2517 fclose (fp);
2518 if (buf)
2520 xfree (buf);
2521 buf = NULL;
2525 return buf;
2530 /***********************************************************************
2531 XBM images
2532 ***********************************************************************/
2534 static int xbm_scan P_ ((unsigned char **, unsigned char *, char *, int *));
2535 static int xbm_load P_ ((struct frame *f, struct image *img));
2536 static int xbm_load_image P_ ((struct frame *f, struct image *img,
2537 unsigned char *, unsigned char *));
2538 static int xbm_image_p P_ ((Lisp_Object object));
2539 static int xbm_read_bitmap_data P_ ((struct frame *f,
2540 unsigned char *, unsigned char *,
2541 int *, int *, unsigned char **));
2542 static int xbm_file_p P_ ((Lisp_Object));
2545 /* Indices of image specification fields in xbm_format, below. */
2547 enum xbm_keyword_index
2549 XBM_TYPE,
2550 XBM_FILE,
2551 XBM_WIDTH,
2552 XBM_HEIGHT,
2553 XBM_DATA,
2554 XBM_FOREGROUND,
2555 XBM_BACKGROUND,
2556 XBM_ASCENT,
2557 XBM_MARGIN,
2558 XBM_RELIEF,
2559 XBM_ALGORITHM,
2560 XBM_HEURISTIC_MASK,
2561 XBM_MASK,
2562 XBM_LAST
2565 /* Vector of image_keyword structures describing the format
2566 of valid XBM image specifications. */
2568 static struct image_keyword xbm_format[XBM_LAST] =
2570 {":type", IMAGE_SYMBOL_VALUE, 1},
2571 {":file", IMAGE_STRING_VALUE, 0},
2572 {":width", IMAGE_POSITIVE_INTEGER_VALUE, 0},
2573 {":height", IMAGE_POSITIVE_INTEGER_VALUE, 0},
2574 {":data", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
2575 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
2576 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
2577 {":ascent", IMAGE_ASCENT_VALUE, 0},
2578 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
2579 {":relief", IMAGE_INTEGER_VALUE, 0},
2580 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
2581 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
2582 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
2585 /* Structure describing the image type XBM. */
2587 static struct image_type xbm_type =
2589 &Qxbm,
2590 xbm_image_p,
2591 xbm_load,
2592 x_clear_image,
2593 NULL
2596 /* Tokens returned from xbm_scan. */
2598 enum xbm_token
2600 XBM_TK_IDENT = 256,
2601 XBM_TK_NUMBER
2605 /* Return non-zero if OBJECT is a valid XBM-type image specification.
2606 A valid specification is a list starting with the symbol `image'
2607 The rest of the list is a property list which must contain an
2608 entry `:type xbm..
2610 If the specification specifies a file to load, it must contain
2611 an entry `:file FILENAME' where FILENAME is a string.
2613 If the specification is for a bitmap loaded from memory it must
2614 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
2615 WIDTH and HEIGHT are integers > 0. DATA may be:
2617 1. a string large enough to hold the bitmap data, i.e. it must
2618 have a size >= (WIDTH + 7) / 8 * HEIGHT
2620 2. a bool-vector of size >= WIDTH * HEIGHT
2622 3. a vector of strings or bool-vectors, one for each line of the
2623 bitmap.
2625 4. a string containing an in-memory XBM file. WIDTH and HEIGHT
2626 may not be specified in this case because they are defined in the
2627 XBM file.
2629 Both the file and data forms may contain the additional entries
2630 `:background COLOR' and `:foreground COLOR'. If not present,
2631 foreground and background of the frame on which the image is
2632 displayed is used. */
2634 static int
2635 xbm_image_p (object)
2636 Lisp_Object object;
2638 struct image_keyword kw[XBM_LAST];
2640 bcopy (xbm_format, kw, sizeof kw);
2641 if (!parse_image_spec (object, kw, XBM_LAST, Qxbm))
2642 return 0;
2644 xassert (EQ (kw[XBM_TYPE].value, Qxbm));
2646 if (kw[XBM_FILE].count)
2648 if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_DATA].count)
2649 return 0;
2651 else if (kw[XBM_DATA].count && xbm_file_p (kw[XBM_DATA].value))
2653 /* In-memory XBM file. */
2654 if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_FILE].count)
2655 return 0;
2657 else
2659 Lisp_Object data;
2660 int width, height;
2662 /* Entries for `:width', `:height' and `:data' must be present. */
2663 if (!kw[XBM_WIDTH].count
2664 || !kw[XBM_HEIGHT].count
2665 || !kw[XBM_DATA].count)
2666 return 0;
2668 data = kw[XBM_DATA].value;
2669 width = XFASTINT (kw[XBM_WIDTH].value);
2670 height = XFASTINT (kw[XBM_HEIGHT].value);
2672 /* Check type of data, and width and height against contents of
2673 data. */
2674 if (VECTORP (data))
2676 int i;
2678 /* Number of elements of the vector must be >= height. */
2679 if (XVECTOR (data)->size < height)
2680 return 0;
2682 /* Each string or bool-vector in data must be large enough
2683 for one line of the image. */
2684 for (i = 0; i < height; ++i)
2686 Lisp_Object elt = XVECTOR (data)->contents[i];
2688 if (STRINGP (elt))
2690 if (SCHARS (elt)
2691 < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR)
2692 return 0;
2694 else if (BOOL_VECTOR_P (elt))
2696 if (XBOOL_VECTOR (elt)->size < width)
2697 return 0;
2699 else
2700 return 0;
2703 else if (STRINGP (data))
2705 if (SCHARS (data)
2706 < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR * height)
2707 return 0;
2709 else if (BOOL_VECTOR_P (data))
2711 if (XBOOL_VECTOR (data)->size < width * height)
2712 return 0;
2714 else
2715 return 0;
2718 return 1;
2722 /* Scan a bitmap file. FP is the stream to read from. Value is
2723 either an enumerator from enum xbm_token, or a character for a
2724 single-character token, or 0 at end of file. If scanning an
2725 identifier, store the lexeme of the identifier in SVAL. If
2726 scanning a number, store its value in *IVAL. */
2728 static int
2729 xbm_scan (s, end, sval, ival)
2730 unsigned char **s, *end;
2731 char *sval;
2732 int *ival;
2734 unsigned int c;
2736 loop:
2738 /* Skip white space. */
2739 while (*s < end && (c = *(*s)++, isspace (c)))
2742 if (*s >= end)
2743 c = 0;
2744 else if (isdigit (c))
2746 int value = 0, digit;
2748 if (c == '0' && *s < end)
2750 c = *(*s)++;
2751 if (c == 'x' || c == 'X')
2753 while (*s < end)
2755 c = *(*s)++;
2756 if (isdigit (c))
2757 digit = c - '0';
2758 else if (c >= 'a' && c <= 'f')
2759 digit = c - 'a' + 10;
2760 else if (c >= 'A' && c <= 'F')
2761 digit = c - 'A' + 10;
2762 else
2763 break;
2764 value = 16 * value + digit;
2767 else if (isdigit (c))
2769 value = c - '0';
2770 while (*s < end
2771 && (c = *(*s)++, isdigit (c)))
2772 value = 8 * value + c - '0';
2775 else
2777 value = c - '0';
2778 while (*s < end
2779 && (c = *(*s)++, isdigit (c)))
2780 value = 10 * value + c - '0';
2783 if (*s < end)
2784 *s = *s - 1;
2785 *ival = value;
2786 c = XBM_TK_NUMBER;
2788 else if (isalpha (c) || c == '_')
2790 *sval++ = c;
2791 while (*s < end
2792 && (c = *(*s)++, (isalnum (c) || c == '_')))
2793 *sval++ = c;
2794 *sval = 0;
2795 if (*s < end)
2796 *s = *s - 1;
2797 c = XBM_TK_IDENT;
2799 else if (c == '/' && **s == '*')
2801 /* C-style comment. */
2802 ++*s;
2803 while (**s && (**s != '*' || *(*s + 1) != '/'))
2804 ++*s;
2805 if (**s)
2807 *s += 2;
2808 goto loop;
2812 return c;
2815 #ifdef HAVE_NTGUI
2817 /* Create a Windows bitmap from X bitmap data. */
2818 static HBITMAP
2819 w32_create_pixmap_from_bitmap_data (int width, int height, char *data)
2821 static unsigned char swap_nibble[16]
2822 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
2823 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
2824 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
2825 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
2826 int i, j, w1, w2;
2827 unsigned char *bits, *p;
2828 HBITMAP bmp;
2830 w1 = (width + 7) / 8; /* nb of 8bits elt in X bitmap */
2831 w2 = ((width + 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
2832 bits = (unsigned char *) alloca (height * w2);
2833 bzero (bits, height * w2);
2834 for (i = 0; i < height; i++)
2836 p = bits + i*w2;
2837 for (j = 0; j < w1; j++)
2839 /* Bitswap XBM bytes to match how Windows does things. */
2840 unsigned char c = *data++;
2841 *p++ = (unsigned char)((swap_nibble[c & 0xf] << 4)
2842 | (swap_nibble[(c>>4) & 0xf]));
2845 bmp = CreateBitmap (width, height, 1, 1, (char *) bits);
2847 return bmp;
2850 static void
2851 convert_mono_to_color_image (f, img, foreground, background)
2852 struct frame *f;
2853 struct image *img;
2854 COLORREF foreground, background;
2856 HDC hdc, old_img_dc, new_img_dc;
2857 HGDIOBJ old_prev, new_prev;
2858 HBITMAP new_pixmap;
2860 hdc = get_frame_dc (f);
2861 old_img_dc = CreateCompatibleDC (hdc);
2862 new_img_dc = CreateCompatibleDC (hdc);
2863 new_pixmap = CreateCompatibleBitmap (hdc, img->width, img->height);
2864 release_frame_dc (f, hdc);
2865 old_prev = SelectObject (old_img_dc, img->pixmap);
2866 new_prev = SelectObject (new_img_dc, new_pixmap);
2867 /* Windows convention for mono bitmaps is black = background,
2868 white = foreground. */
2869 SetTextColor (new_img_dc, background);
2870 SetBkColor (new_img_dc, foreground);
2872 BitBlt (new_img_dc, 0, 0, img->width, img->height, old_img_dc,
2873 0, 0, SRCCOPY);
2875 SelectObject (old_img_dc, old_prev);
2876 SelectObject (new_img_dc, new_prev);
2877 DeleteDC (old_img_dc);
2878 DeleteDC (new_img_dc);
2879 DeleteObject (img->pixmap);
2880 if (new_pixmap == 0)
2881 fprintf (stderr, "Failed to convert image to color.\n");
2882 else
2883 img->pixmap = new_pixmap;
2886 #define XBM_BIT_SHUFFLE(b) (~(b))
2888 #else
2890 #define XBM_BIT_SHUFFLE(b) (b)
2892 #endif /* HAVE_NTGUI */
2895 static void
2896 Create_Pixmap_From_Bitmap_Data (f, img, data, fg, bg, non_default_colors)
2897 struct frame *f;
2898 struct image *img;
2899 char *data;
2900 RGB_PIXEL_COLOR fg, bg;
2901 int non_default_colors;
2903 #ifdef HAVE_NTGUI
2904 img->pixmap
2905 = w32_create_pixmap_from_bitmap_data (img->width, img->height, data);
2907 /* If colors were specified, transfer the bitmap to a color one. */
2908 if (non_default_colors)
2909 convert_mono_to_color_image (f, img, fg, bg);
2911 #elif defined (HAVE_NS)
2912 img->pixmap = ns_image_from_XBM(data, img->width, img->height);
2914 #else
2915 img->pixmap
2916 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
2917 FRAME_X_WINDOW (f),
2918 data,
2919 img->width, img->height,
2920 fg, bg,
2921 DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
2922 #endif /* !HAVE_NTGUI && !HAVE_NS */
2927 /* Replacement for XReadBitmapFileData which isn't available under old
2928 X versions. CONTENTS is a pointer to a buffer to parse; END is the
2929 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
2930 the image. Return in *DATA the bitmap data allocated with xmalloc.
2931 Value is non-zero if successful. DATA null means just test if
2932 CONTENTS looks like an in-memory XBM file. */
2934 static int
2935 xbm_read_bitmap_data (f, contents, end, width, height, data)
2936 struct frame *f;
2937 unsigned char *contents, *end;
2938 int *width, *height;
2939 unsigned char **data;
2941 unsigned char *s = contents;
2942 char buffer[BUFSIZ];
2943 int padding_p = 0;
2944 int v10 = 0;
2945 int bytes_per_line, i, nbytes;
2946 unsigned char *p;
2947 int value;
2948 int LA1;
2950 #define match() \
2951 LA1 = xbm_scan (&s, end, buffer, &value)
2953 #define expect(TOKEN) \
2954 if (LA1 != (TOKEN)) \
2955 goto failure; \
2956 else \
2957 match ()
2959 #define expect_ident(IDENT) \
2960 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
2961 match (); \
2962 else \
2963 goto failure
2965 *width = *height = -1;
2966 if (data)
2967 *data = NULL;
2968 LA1 = xbm_scan (&s, end, buffer, &value);
2970 /* Parse defines for width, height and hot-spots. */
2971 while (LA1 == '#')
2973 match ();
2974 expect_ident ("define");
2975 expect (XBM_TK_IDENT);
2977 if (LA1 == XBM_TK_NUMBER)
2979 char *p = strrchr (buffer, '_');
2980 p = p ? p + 1 : buffer;
2981 if (strcmp (p, "width") == 0)
2982 *width = value;
2983 else if (strcmp (p, "height") == 0)
2984 *height = value;
2986 expect (XBM_TK_NUMBER);
2989 if (!check_image_size (f, *width, *height))
2990 goto failure;
2991 else if (data == NULL)
2992 goto success;
2994 /* Parse bits. Must start with `static'. */
2995 expect_ident ("static");
2996 if (LA1 == XBM_TK_IDENT)
2998 if (strcmp (buffer, "unsigned") == 0)
3000 match ();
3001 expect_ident ("char");
3003 else if (strcmp (buffer, "short") == 0)
3005 match ();
3006 v10 = 1;
3007 if (*width % 16 && *width % 16 < 9)
3008 padding_p = 1;
3010 else if (strcmp (buffer, "char") == 0)
3011 match ();
3012 else
3013 goto failure;
3015 else
3016 goto failure;
3018 expect (XBM_TK_IDENT);
3019 expect ('[');
3020 expect (']');
3021 expect ('=');
3022 expect ('{');
3024 bytes_per_line = (*width + 7) / 8 + padding_p;
3025 nbytes = bytes_per_line * *height;
3026 p = *data = (unsigned char *) xmalloc (nbytes);
3028 if (v10)
3030 for (i = 0; i < nbytes; i += 2)
3032 int val = value;
3033 expect (XBM_TK_NUMBER);
3035 *p++ = XBM_BIT_SHUFFLE (val);
3036 if (!padding_p || ((i + 2) % bytes_per_line))
3037 *p++ = XBM_BIT_SHUFFLE (value >> 8);
3039 if (LA1 == ',' || LA1 == '}')
3040 match ();
3041 else
3042 goto failure;
3045 else
3047 for (i = 0; i < nbytes; ++i)
3049 int val = value;
3050 expect (XBM_TK_NUMBER);
3052 *p++ = XBM_BIT_SHUFFLE (val);
3054 if (LA1 == ',' || LA1 == '}')
3055 match ();
3056 else
3057 goto failure;
3061 success:
3062 return 1;
3064 failure:
3066 if (data && *data)
3068 xfree (*data);
3069 *data = NULL;
3071 return 0;
3073 #undef match
3074 #undef expect
3075 #undef expect_ident
3079 /* Load XBM image IMG which will be displayed on frame F from buffer
3080 CONTENTS. END is the end of the buffer. Value is non-zero if
3081 successful. */
3083 static int
3084 xbm_load_image (f, img, contents, end)
3085 struct frame *f;
3086 struct image *img;
3087 unsigned char *contents, *end;
3089 int rc;
3090 unsigned char *data;
3091 int success_p = 0;
3093 rc = xbm_read_bitmap_data (f, contents, end, &img->width, &img->height, &data);
3094 if (rc)
3096 unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
3097 unsigned long background = FRAME_BACKGROUND_PIXEL (f);
3098 int non_default_colors = 0;
3099 Lisp_Object value;
3101 xassert (img->width > 0 && img->height > 0);
3103 /* Get foreground and background colors, maybe allocate colors. */
3104 value = image_spec_value (img->spec, QCforeground, NULL);
3105 if (!NILP (value))
3107 foreground = x_alloc_image_color (f, img, value, foreground);
3108 non_default_colors = 1;
3110 value = image_spec_value (img->spec, QCbackground, NULL);
3111 if (!NILP (value))
3113 background = x_alloc_image_color (f, img, value, background);
3114 img->background = background;
3115 img->background_valid = 1;
3116 non_default_colors = 1;
3119 Create_Pixmap_From_Bitmap_Data (f, img, data,
3120 foreground, background,
3121 non_default_colors);
3122 xfree (data);
3124 if (img->pixmap == NO_PIXMAP)
3126 x_clear_image (f, img);
3127 image_error ("Unable to create X pixmap for `%s'", img->spec, Qnil);
3129 else
3130 success_p = 1;
3132 else
3133 image_error ("Error loading XBM image `%s'", img->spec, Qnil);
3135 return success_p;
3139 /* Value is non-zero if DATA looks like an in-memory XBM file. */
3141 static int
3142 xbm_file_p (data)
3143 Lisp_Object data;
3145 int w, h;
3146 return (STRINGP (data)
3147 && xbm_read_bitmap_data (NULL, SDATA (data),
3148 (SDATA (data)
3149 + SBYTES (data)),
3150 &w, &h, NULL));
3154 /* Fill image IMG which is used on frame F with pixmap data. Value is
3155 non-zero if successful. */
3157 static int
3158 xbm_load (f, img)
3159 struct frame *f;
3160 struct image *img;
3162 int success_p = 0;
3163 Lisp_Object file_name;
3165 xassert (xbm_image_p (img->spec));
3167 /* If IMG->spec specifies a file name, create a non-file spec from it. */
3168 file_name = image_spec_value (img->spec, QCfile, NULL);
3169 if (STRINGP (file_name))
3171 Lisp_Object file;
3172 unsigned char *contents;
3173 int size;
3174 struct gcpro gcpro1;
3176 file = x_find_image_file (file_name);
3177 GCPRO1 (file);
3178 if (!STRINGP (file))
3180 image_error ("Cannot find image file `%s'", file_name, Qnil);
3181 UNGCPRO;
3182 return 0;
3185 contents = slurp_file (SDATA (file), &size);
3186 if (contents == NULL)
3188 image_error ("Error loading XBM image `%s'", img->spec, Qnil);
3189 UNGCPRO;
3190 return 0;
3193 success_p = xbm_load_image (f, img, contents, contents + size);
3194 UNGCPRO;
3196 else
3198 struct image_keyword fmt[XBM_LAST];
3199 Lisp_Object data;
3200 unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
3201 unsigned long background = FRAME_BACKGROUND_PIXEL (f);
3202 int non_default_colors = 0;
3203 char *bits;
3204 int parsed_p;
3205 int in_memory_file_p = 0;
3207 /* See if data looks like an in-memory XBM file. */
3208 data = image_spec_value (img->spec, QCdata, NULL);
3209 in_memory_file_p = xbm_file_p (data);
3211 /* Parse the image specification. */
3212 bcopy (xbm_format, fmt, sizeof fmt);
3213 parsed_p = parse_image_spec (img->spec, fmt, XBM_LAST, Qxbm);
3214 xassert (parsed_p);
3216 /* Get specified width, and height. */
3217 if (!in_memory_file_p)
3219 img->width = XFASTINT (fmt[XBM_WIDTH].value);
3220 img->height = XFASTINT (fmt[XBM_HEIGHT].value);
3221 xassert (img->width > 0 && img->height > 0);
3224 /* Get foreground and background colors, maybe allocate colors. */
3225 if (fmt[XBM_FOREGROUND].count
3226 && STRINGP (fmt[XBM_FOREGROUND].value))
3228 foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value,
3229 foreground);
3230 non_default_colors = 1;
3233 if (fmt[XBM_BACKGROUND].count
3234 && STRINGP (fmt[XBM_BACKGROUND].value))
3236 background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value,
3237 background);
3238 non_default_colors = 1;
3241 if (in_memory_file_p)
3242 success_p = xbm_load_image (f, img, SDATA (data),
3243 (SDATA (data)
3244 + SBYTES (data)));
3245 else
3247 if (VECTORP (data))
3249 int i;
3250 char *p;
3251 int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
3253 p = bits = (char *) alloca (nbytes * img->height);
3254 for (i = 0; i < img->height; ++i, p += nbytes)
3256 Lisp_Object line = XVECTOR (data)->contents[i];
3257 if (STRINGP (line))
3258 bcopy (SDATA (line), p, nbytes);
3259 else
3260 bcopy (XBOOL_VECTOR (line)->data, p, nbytes);
3263 else if (STRINGP (data))
3264 bits = SDATA (data);
3265 else
3266 bits = XBOOL_VECTOR (data)->data;
3268 #ifdef WINDOWSNT
3270 char *invertedBits;
3271 int nbytes, i;
3272 /* Windows mono bitmaps are reversed compared with X. */
3273 invertedBits = bits;
3274 nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR
3275 * img->height;
3276 bits = (char *) alloca(nbytes);
3277 for (i = 0; i < nbytes; i++)
3278 bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]);
3280 #endif
3281 /* Create the pixmap. */
3283 Create_Pixmap_From_Bitmap_Data (f, img, bits,
3284 foreground, background,
3285 non_default_colors);
3286 if (img->pixmap)
3287 success_p = 1;
3288 else
3290 image_error ("Unable to create pixmap for XBM image `%s'",
3291 img->spec, Qnil);
3292 x_clear_image (f, img);
3297 return success_p;
3302 /***********************************************************************
3303 XPM images
3304 ***********************************************************************/
3306 #if defined (HAVE_XPM) || defined (HAVE_NS)
3308 static int xpm_image_p P_ ((Lisp_Object object));
3309 static int xpm_load P_ ((struct frame *f, struct image *img));
3310 static int xpm_valid_color_symbols_p P_ ((Lisp_Object));
3312 #endif /* HAVE_XPM || HAVE_NS */
3314 #ifdef HAVE_XPM
3315 #ifdef HAVE_NTGUI
3316 /* Indicate to xpm.h that we don't have Xlib. */
3317 #define FOR_MSW
3318 /* simx.h in xpm defines XColor and XImage differently than Emacs. */
3319 /* It also defines Display the same way as Emacs, but gcc 3.3 still barfs. */
3320 #define XColor xpm_XColor
3321 #define XImage xpm_XImage
3322 #define Display xpm_Display
3323 #define PIXEL_ALREADY_TYPEDEFED
3324 #include "X11/xpm.h"
3325 #undef FOR_MSW
3326 #undef XColor
3327 #undef XImage
3328 #undef Display
3329 #undef PIXEL_ALREADY_TYPEDEFED
3330 #else
3331 #include "X11/xpm.h"
3332 #endif /* HAVE_NTGUI */
3333 #endif /* HAVE_XPM */
3335 #if defined (HAVE_XPM) || defined (HAVE_NS)
3336 /* The symbol `xpm' identifying XPM-format images. */
3338 Lisp_Object Qxpm;
3340 /* Indices of image specification fields in xpm_format, below. */
3342 enum xpm_keyword_index
3344 XPM_TYPE,
3345 XPM_FILE,
3346 XPM_DATA,
3347 XPM_ASCENT,
3348 XPM_MARGIN,
3349 XPM_RELIEF,
3350 XPM_ALGORITHM,
3351 XPM_HEURISTIC_MASK,
3352 XPM_MASK,
3353 XPM_COLOR_SYMBOLS,
3354 XPM_BACKGROUND,
3355 XPM_LAST
3358 /* Vector of image_keyword structures describing the format
3359 of valid XPM image specifications. */
3361 static struct image_keyword xpm_format[XPM_LAST] =
3363 {":type", IMAGE_SYMBOL_VALUE, 1},
3364 {":file", IMAGE_STRING_VALUE, 0},
3365 {":data", IMAGE_STRING_VALUE, 0},
3366 {":ascent", IMAGE_ASCENT_VALUE, 0},
3367 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
3368 {":relief", IMAGE_INTEGER_VALUE, 0},
3369 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3370 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3371 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3372 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3373 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
3376 /* Structure describing the image type XPM. */
3378 static struct image_type xpm_type =
3380 &Qxpm,
3381 xpm_image_p,
3382 xpm_load,
3383 x_clear_image,
3384 NULL
3387 #ifdef HAVE_X_WINDOWS
3389 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
3390 functions for allocating image colors. Our own functions handle
3391 color allocation failures more gracefully than the ones on the XPM
3392 lib. */
3394 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
3395 #define ALLOC_XPM_COLORS
3396 #endif
3397 #endif /* HAVE_X_WINDOWS */
3399 #ifdef ALLOC_XPM_COLORS
3401 static void xpm_init_color_cache P_ ((struct frame *, XpmAttributes *));
3402 static void xpm_free_color_cache P_ ((void));
3403 static int xpm_lookup_color P_ ((struct frame *, char *, XColor *));
3404 static int xpm_color_bucket P_ ((char *));
3405 static struct xpm_cached_color *xpm_cache_color P_ ((struct frame *, char *,
3406 XColor *, int));
3408 /* An entry in a hash table used to cache color definitions of named
3409 colors. This cache is necessary to speed up XPM image loading in
3410 case we do color allocations ourselves. Without it, we would need
3411 a call to XParseColor per pixel in the image. */
3413 struct xpm_cached_color
3415 /* Next in collision chain. */
3416 struct xpm_cached_color *next;
3418 /* Color definition (RGB and pixel color). */
3419 XColor color;
3421 /* Color name. */
3422 char name[1];
3425 /* The hash table used for the color cache, and its bucket vector
3426 size. */
3428 #define XPM_COLOR_CACHE_BUCKETS 1001
3429 struct xpm_cached_color **xpm_color_cache;
3431 /* Initialize the color cache. */
3433 static void
3434 xpm_init_color_cache (f, attrs)
3435 struct frame *f;
3436 XpmAttributes *attrs;
3438 size_t nbytes = XPM_COLOR_CACHE_BUCKETS * sizeof *xpm_color_cache;
3439 xpm_color_cache = (struct xpm_cached_color **) xmalloc (nbytes);
3440 memset (xpm_color_cache, 0, nbytes);
3441 init_color_table ();
3443 if (attrs->valuemask & XpmColorSymbols)
3445 int i;
3446 XColor color;
3448 for (i = 0; i < attrs->numsymbols; ++i)
3449 if (XParseColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
3450 attrs->colorsymbols[i].value, &color))
3452 color.pixel = lookup_rgb_color (f, color.red, color.green,
3453 color.blue);
3454 xpm_cache_color (f, attrs->colorsymbols[i].name, &color, -1);
3459 /* Free the color cache. */
3461 static void
3462 xpm_free_color_cache ()
3464 struct xpm_cached_color *p, *next;
3465 int i;
3467 for (i = 0; i < XPM_COLOR_CACHE_BUCKETS; ++i)
3468 for (p = xpm_color_cache[i]; p; p = next)
3470 next = p->next;
3471 xfree (p);
3474 xfree (xpm_color_cache);
3475 xpm_color_cache = NULL;
3476 free_color_table ();
3479 /* Return the bucket index for color named COLOR_NAME in the color
3480 cache. */
3482 static int
3483 xpm_color_bucket (color_name)
3484 char *color_name;
3486 unsigned h = 0;
3487 char *s;
3489 for (s = color_name; *s; ++s)
3490 h = (h << 2) ^ *s;
3491 return h %= XPM_COLOR_CACHE_BUCKETS;
3495 /* On frame F, cache values COLOR for color with name COLOR_NAME.
3496 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
3497 entry added. */
3499 static struct xpm_cached_color *
3500 xpm_cache_color (f, color_name, color, bucket)
3501 struct frame *f;
3502 char *color_name;
3503 XColor *color;
3504 int bucket;
3506 size_t nbytes;
3507 struct xpm_cached_color *p;
3509 if (bucket < 0)
3510 bucket = xpm_color_bucket (color_name);
3512 nbytes = sizeof *p + strlen (color_name);
3513 p = (struct xpm_cached_color *) xmalloc (nbytes);
3514 strcpy (p->name, color_name);
3515 p->color = *color;
3516 p->next = xpm_color_cache[bucket];
3517 xpm_color_cache[bucket] = p;
3518 return p;
3521 /* Look up color COLOR_NAME for frame F in the color cache. If found,
3522 return the cached definition in *COLOR. Otherwise, make a new
3523 entry in the cache and allocate the color. Value is zero if color
3524 allocation failed. */
3526 static int
3527 xpm_lookup_color (f, color_name, color)
3528 struct frame *f;
3529 char *color_name;
3530 XColor *color;
3532 struct xpm_cached_color *p;
3533 int h = xpm_color_bucket (color_name);
3535 for (p = xpm_color_cache[h]; p; p = p->next)
3536 if (strcmp (p->name, color_name) == 0)
3537 break;
3539 if (p != NULL)
3540 *color = p->color;
3541 else if (XParseColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
3542 color_name, color))
3544 color->pixel = lookup_rgb_color (f, color->red, color->green,
3545 color->blue);
3546 p = xpm_cache_color (f, color_name, color, h);
3548 /* You get `opaque' at least from ImageMagick converting pbm to xpm
3549 with transparency, and it's useful. */
3550 else if (strcmp ("opaque", color_name) == 0)
3552 bzero (color, sizeof (XColor)); /* Is this necessary/correct? */
3553 color->pixel = FRAME_FOREGROUND_PIXEL (f);
3554 p = xpm_cache_color (f, color_name, color, h);
3557 return p != NULL;
3561 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
3562 CLOSURE is a pointer to the frame on which we allocate the
3563 color. Return in *COLOR the allocated color. Value is non-zero
3564 if successful. */
3566 static int
3567 xpm_alloc_color (dpy, cmap, color_name, color, closure)
3568 Display *dpy;
3569 Colormap cmap;
3570 char *color_name;
3571 XColor *color;
3572 void *closure;
3574 return xpm_lookup_color ((struct frame *) closure, color_name, color);
3578 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
3579 is a pointer to the frame on which we allocate the color. Value is
3580 non-zero if successful. */
3582 static int
3583 xpm_free_colors (dpy, cmap, pixels, npixels, closure)
3584 Display *dpy;
3585 Colormap cmap;
3586 Pixel *pixels;
3587 int npixels;
3588 void *closure;
3590 return 1;
3593 #endif /* ALLOC_XPM_COLORS */
3596 #ifdef HAVE_NTGUI
3598 /* XPM library details. */
3600 DEF_IMGLIB_FN (XpmFreeAttributes);
3601 DEF_IMGLIB_FN (XpmCreateImageFromBuffer);
3602 DEF_IMGLIB_FN (XpmReadFileToImage);
3603 DEF_IMGLIB_FN (XImageFree);
3605 static int
3606 init_xpm_functions (Lisp_Object libraries)
3608 HMODULE library;
3610 if (!(library = w32_delayed_load (libraries, Qxpm)))
3611 return 0;
3613 LOAD_IMGLIB_FN (library, XpmFreeAttributes);
3614 LOAD_IMGLIB_FN (library, XpmCreateImageFromBuffer);
3615 LOAD_IMGLIB_FN (library, XpmReadFileToImage);
3616 LOAD_IMGLIB_FN (library, XImageFree);
3617 return 1;
3620 #endif /* HAVE_NTGUI */
3623 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
3624 for XPM images. Such a list must consist of conses whose car and
3625 cdr are strings. */
3627 static int
3628 xpm_valid_color_symbols_p (color_symbols)
3629 Lisp_Object color_symbols;
3631 while (CONSP (color_symbols))
3633 Lisp_Object sym = XCAR (color_symbols);
3634 if (!CONSP (sym)
3635 || !STRINGP (XCAR (sym))
3636 || !STRINGP (XCDR (sym)))
3637 break;
3638 color_symbols = XCDR (color_symbols);
3641 return NILP (color_symbols);
3645 /* Value is non-zero if OBJECT is a valid XPM image specification. */
3647 static int
3648 xpm_image_p (object)
3649 Lisp_Object object;
3651 struct image_keyword fmt[XPM_LAST];
3652 bcopy (xpm_format, fmt, sizeof fmt);
3653 return (parse_image_spec (object, fmt, XPM_LAST, Qxpm)
3654 /* Either `:file' or `:data' must be present. */
3655 && fmt[XPM_FILE].count + fmt[XPM_DATA].count == 1
3656 /* Either no `:color-symbols' or it's a list of conses
3657 whose car and cdr are strings. */
3658 && (fmt[XPM_COLOR_SYMBOLS].count == 0
3659 || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
3662 #endif /* HAVE_XPM || HAVE_NS */
3664 #if defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
3666 x_create_bitmap_from_xpm_data (f, bits)
3667 struct frame *f;
3668 char **bits;
3670 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3671 int id, rc;
3672 XpmAttributes attrs;
3673 Pixmap bitmap, mask;
3675 bzero (&attrs, sizeof attrs);
3677 attrs.visual = FRAME_X_VISUAL (f);
3678 attrs.colormap = FRAME_X_COLORMAP (f);
3679 attrs.valuemask |= XpmVisual;
3680 attrs.valuemask |= XpmColormap;
3682 rc = XpmCreatePixmapFromData (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3683 bits, &bitmap, &mask, &attrs);
3684 if (rc != XpmSuccess)
3686 XpmFreeAttributes (&attrs);
3687 return -1;
3690 id = x_allocate_bitmap_record (f);
3691 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
3692 dpyinfo->bitmaps[id - 1].have_mask = 1;
3693 dpyinfo->bitmaps[id - 1].mask = mask;
3694 dpyinfo->bitmaps[id - 1].file = NULL;
3695 dpyinfo->bitmaps[id - 1].height = attrs.height;
3696 dpyinfo->bitmaps[id - 1].width = attrs.width;
3697 dpyinfo->bitmaps[id - 1].depth = attrs.depth;
3698 dpyinfo->bitmaps[id - 1].refcount = 1;
3700 XpmFreeAttributes (&attrs);
3701 return id;
3703 #endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */
3705 /* Load image IMG which will be displayed on frame F. Value is
3706 non-zero if successful. */
3708 #ifdef HAVE_XPM
3710 static int
3711 xpm_load (f, img)
3712 struct frame *f;
3713 struct image *img;
3715 int rc;
3716 XpmAttributes attrs;
3717 Lisp_Object specified_file, color_symbols;
3718 #ifdef HAVE_NTGUI
3719 HDC hdc;
3720 xpm_XImage * xpm_image = NULL, * xpm_mask = NULL;
3721 #endif /* HAVE_NTGUI */
3723 /* Configure the XPM lib. Use the visual of frame F. Allocate
3724 close colors. Return colors allocated. */
3725 bzero (&attrs, sizeof attrs);
3727 #ifndef HAVE_NTGUI
3728 attrs.visual = FRAME_X_VISUAL (f);
3729 attrs.colormap = FRAME_X_COLORMAP (f);
3730 attrs.valuemask |= XpmVisual;
3731 attrs.valuemask |= XpmColormap;
3732 #endif /* HAVE_NTGUI */
3734 #ifdef ALLOC_XPM_COLORS
3735 /* Allocate colors with our own functions which handle
3736 failing color allocation more gracefully. */
3737 attrs.color_closure = f;
3738 attrs.alloc_color = xpm_alloc_color;
3739 attrs.free_colors = xpm_free_colors;
3740 attrs.valuemask |= XpmAllocColor | XpmFreeColors | XpmColorClosure;
3741 #else /* not ALLOC_XPM_COLORS */
3742 /* Let the XPM lib allocate colors. */
3743 attrs.valuemask |= XpmReturnAllocPixels;
3744 #ifdef XpmAllocCloseColors
3745 attrs.alloc_close_colors = 1;
3746 attrs.valuemask |= XpmAllocCloseColors;
3747 #else /* not XpmAllocCloseColors */
3748 attrs.closeness = 600;
3749 attrs.valuemask |= XpmCloseness;
3750 #endif /* not XpmAllocCloseColors */
3751 #endif /* ALLOC_XPM_COLORS */
3753 /* If image specification contains symbolic color definitions, add
3754 these to `attrs'. */
3755 color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL);
3756 if (CONSP (color_symbols))
3758 Lisp_Object tail;
3759 XpmColorSymbol *xpm_syms;
3760 int i, size;
3762 attrs.valuemask |= XpmColorSymbols;
3764 /* Count number of symbols. */
3765 attrs.numsymbols = 0;
3766 for (tail = color_symbols; CONSP (tail); tail = XCDR (tail))
3767 ++attrs.numsymbols;
3769 /* Allocate an XpmColorSymbol array. */
3770 size = attrs.numsymbols * sizeof *xpm_syms;
3771 xpm_syms = (XpmColorSymbol *) alloca (size);
3772 bzero (xpm_syms, size);
3773 attrs.colorsymbols = xpm_syms;
3775 /* Fill the color symbol array. */
3776 for (tail = color_symbols, i = 0;
3777 CONSP (tail);
3778 ++i, tail = XCDR (tail))
3780 Lisp_Object name = XCAR (XCAR (tail));
3781 Lisp_Object color = XCDR (XCAR (tail));
3782 xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1);
3783 strcpy (xpm_syms[i].name, SDATA (name));
3784 xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1);
3785 strcpy (xpm_syms[i].value, SDATA (color));
3789 /* Create a pixmap for the image, either from a file, or from a
3790 string buffer containing data in the same format as an XPM file. */
3791 #ifdef ALLOC_XPM_COLORS
3792 xpm_init_color_cache (f, &attrs);
3793 #endif
3795 specified_file = image_spec_value (img->spec, QCfile, NULL);
3797 #ifdef HAVE_NTGUI
3799 HDC frame_dc = get_frame_dc (f);
3800 hdc = CreateCompatibleDC (frame_dc);
3801 release_frame_dc (f, frame_dc);
3803 #endif /* HAVE_NTGUI */
3805 if (STRINGP (specified_file))
3807 Lisp_Object file = x_find_image_file (specified_file);
3808 if (!STRINGP (file))
3810 image_error ("Cannot find image file `%s'", specified_file, Qnil);
3811 return 0;
3814 #ifdef HAVE_NTGUI
3815 /* XpmReadFileToPixmap is not available in the Windows port of
3816 libxpm. But XpmReadFileToImage almost does what we want. */
3817 rc = fn_XpmReadFileToImage (&hdc, SDATA (file),
3818 &xpm_image, &xpm_mask,
3819 &attrs);
3820 #else
3821 rc = XpmReadFileToPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3822 SDATA (file), &img->pixmap, &img->mask,
3823 &attrs);
3824 #endif /* HAVE_NTGUI */
3826 else
3828 Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);
3829 #ifdef HAVE_NTGUI
3830 /* XpmCreatePixmapFromBuffer is not available in the Windows port
3831 of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
3832 rc = fn_XpmCreateImageFromBuffer (&hdc, SDATA (buffer),
3833 &xpm_image, &xpm_mask,
3834 &attrs);
3835 #else
3836 rc = XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3837 SDATA (buffer),
3838 &img->pixmap, &img->mask,
3839 &attrs);
3840 #endif /* HAVE_NTGUI */
3843 if (rc == XpmSuccess)
3845 #if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS)
3846 img->colors = colors_in_color_table (&img->ncolors);
3847 #else /* not ALLOC_XPM_COLORS */
3848 int i;
3850 #ifdef HAVE_NTGUI
3851 /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
3852 plus some duplicate attributes. */
3853 if (xpm_image && xpm_image->bitmap)
3855 img->pixmap = xpm_image->bitmap;
3856 /* XImageFree in libXpm frees XImage struct without destroying
3857 the bitmap, which is what we want. */
3858 fn_XImageFree (xpm_image);
3860 if (xpm_mask && xpm_mask->bitmap)
3862 /* The mask appears to be inverted compared with what we expect.
3863 TODO: invert our expectations. See other places where we
3864 have to invert bits because our idea of masks is backwards. */
3865 HGDIOBJ old_obj;
3866 old_obj = SelectObject (hdc, xpm_mask->bitmap);
3868 PatBlt (hdc, 0, 0, xpm_mask->width, xpm_mask->height, DSTINVERT);
3869 SelectObject (hdc, old_obj);
3871 img->mask = xpm_mask->bitmap;
3872 fn_XImageFree (xpm_mask);
3873 DeleteDC (hdc);
3876 DeleteDC (hdc);
3877 #endif /* HAVE_NTGUI */
3879 /* Remember allocated colors. */
3880 img->ncolors = attrs.nalloc_pixels;
3881 img->colors = (unsigned long *) xmalloc (img->ncolors
3882 * sizeof *img->colors);
3883 for (i = 0; i < attrs.nalloc_pixels; ++i)
3885 img->colors[i] = attrs.alloc_pixels[i];
3886 #ifdef DEBUG_X_COLORS
3887 register_color (img->colors[i]);
3888 #endif
3890 #endif /* not ALLOC_XPM_COLORS */
3892 img->width = attrs.width;
3893 img->height = attrs.height;
3894 xassert (img->width > 0 && img->height > 0);
3896 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
3897 #ifdef HAVE_NTGUI
3898 fn_XpmFreeAttributes (&attrs);
3899 #else
3900 XpmFreeAttributes (&attrs);
3901 #endif /* HAVE_NTGUI */
3903 else
3905 #ifdef HAVE_NTGUI
3906 DeleteDC (hdc);
3907 #endif /* HAVE_NTGUI */
3909 switch (rc)
3911 case XpmOpenFailed:
3912 image_error ("Error opening XPM file (%s)", img->spec, Qnil);
3913 break;
3915 case XpmFileInvalid:
3916 image_error ("Invalid XPM file (%s)", img->spec, Qnil);
3917 break;
3919 case XpmNoMemory:
3920 image_error ("Out of memory (%s)", img->spec, Qnil);
3921 break;
3923 case XpmColorFailed:
3924 image_error ("Color allocation error (%s)", img->spec, Qnil);
3925 break;
3927 default:
3928 image_error ("Unknown error (%s)", img->spec, Qnil);
3929 break;
3933 #ifdef ALLOC_XPM_COLORS
3934 xpm_free_color_cache ();
3935 #endif
3936 return rc == XpmSuccess;
3939 #endif /* HAVE_XPM */
3941 #if defined (HAVE_NS) && !defined (HAVE_XPM)
3943 /* XPM support functions for NS where libxpm is not available.
3944 Only XPM version 3 (without any extensions) is supported. */
3946 static int xpm_scan P_ ((const unsigned char **, const unsigned char *,
3947 const unsigned char **, int *));
3948 static Lisp_Object xpm_make_color_table_v
3949 P_ ((void (**) (Lisp_Object, const unsigned char *, int, Lisp_Object),
3950 Lisp_Object (**) (Lisp_Object, const unsigned char *, int)));
3951 static void xpm_put_color_table_v P_ ((Lisp_Object, const unsigned char *,
3952 int, Lisp_Object));
3953 static Lisp_Object xpm_get_color_table_v P_ ((Lisp_Object,
3954 const unsigned char *, int));
3955 static Lisp_Object xpm_make_color_table_h
3956 P_ ((void (**) (Lisp_Object, const unsigned char *, int, Lisp_Object),
3957 Lisp_Object (**) (Lisp_Object, const unsigned char *, int)));
3958 static void xpm_put_color_table_h P_ ((Lisp_Object, const unsigned char *,
3959 int, Lisp_Object));
3960 static Lisp_Object xpm_get_color_table_h P_ ((Lisp_Object,
3961 const unsigned char *, int));
3962 static int xpm_str_to_color_key P_ ((const char *));
3963 static int xpm_load_image P_ ((struct frame *, struct image *,
3964 const unsigned char *, const unsigned char *));
3966 /* Tokens returned from xpm_scan. */
3968 enum xpm_token
3970 XPM_TK_IDENT = 256,
3971 XPM_TK_STRING,
3972 XPM_TK_EOF
3975 /* Scan an XPM data and return a character (< 256) or a token defined
3976 by enum xpm_token above. *S and END are the start (inclusive) and
3977 the end (exclusive) addresses of the data, respectively. Advance
3978 *S while scanning. If token is either XPM_TK_IDENT or
3979 XPM_TK_STRING, *BEG and *LEN are set to the start address and the
3980 length of the corresponding token, respectively. */
3982 static int
3983 xpm_scan (s, end, beg, len)
3984 const unsigned char **s, *end, **beg;
3985 int *len;
3987 int c;
3989 while (*s < end)
3991 /* Skip white-space. */
3992 while (*s < end && (c = *(*s)++, isspace (c)))
3995 /* gnus-pointer.xpm uses '-' in its identifier.
3996 sb-dir-plus.xpm uses '+' in its identifier. */
3997 if (isalpha (c) || c == '_' || c == '-' || c == '+')
3999 *beg = *s - 1;
4000 while (*s < end
4001 && (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+'))
4002 ++*s;
4003 *len = *s - *beg;
4004 return XPM_TK_IDENT;
4006 else if (c == '"')
4008 *beg = *s;
4009 while (*s < end && **s != '"')
4010 ++*s;
4011 *len = *s - *beg;
4012 if (*s < end)
4013 ++*s;
4014 return XPM_TK_STRING;
4016 else if (c == '/')
4018 if (*s < end && **s == '*')
4020 /* C-style comment. */
4021 ++*s;
4024 while (*s < end && *(*s)++ != '*')
4027 while (*s < end && **s != '/');
4028 if (*s < end)
4029 ++*s;
4031 else
4032 return c;
4034 else
4035 return c;
4038 return XPM_TK_EOF;
4041 /* Functions for color table lookup in XPM data. A key is a string
4042 specifying the color of each pixel in XPM data. A value is either
4043 an integer that specifies a pixel color, Qt that specifies
4044 transparency, or Qnil for the unspecified color. If the length of
4045 the key string is one, a vector is used as a table. Otherwise, a
4046 hash table is used. */
4048 static Lisp_Object
4049 xpm_make_color_table_v (put_func, get_func)
4050 void (**put_func) (Lisp_Object, const unsigned char *, int, Lisp_Object);
4051 Lisp_Object (**get_func) (Lisp_Object, const unsigned char *, int);
4053 *put_func = xpm_put_color_table_v;
4054 *get_func = xpm_get_color_table_v;
4055 return Fmake_vector (make_number (256), Qnil);
4058 static void
4059 xpm_put_color_table_v (color_table, chars_start, chars_len, color)
4060 Lisp_Object color_table;
4061 const unsigned char *chars_start;
4062 int chars_len;
4063 Lisp_Object color;
4065 XVECTOR (color_table)->contents[*chars_start] = color;
4068 static Lisp_Object
4069 xpm_get_color_table_v (color_table, chars_start, chars_len)
4070 Lisp_Object color_table;
4071 const unsigned char *chars_start;
4072 int chars_len;
4074 return XVECTOR (color_table)->contents[*chars_start];
4077 static Lisp_Object
4078 xpm_make_color_table_h (put_func, get_func)
4079 void (**put_func) (Lisp_Object, const unsigned char *, int, Lisp_Object);
4080 Lisp_Object (**get_func) (Lisp_Object, const unsigned char *, int);
4082 *put_func = xpm_put_color_table_h;
4083 *get_func = xpm_get_color_table_h;
4084 return make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE),
4085 make_float (DEFAULT_REHASH_SIZE),
4086 make_float (DEFAULT_REHASH_THRESHOLD),
4087 Qnil, Qnil, Qnil);
4090 static void
4091 xpm_put_color_table_h (color_table, chars_start, chars_len, color)
4092 Lisp_Object color_table;
4093 const unsigned char *chars_start;
4094 int chars_len;
4095 Lisp_Object color;
4097 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
4098 unsigned hash_code;
4099 Lisp_Object chars = make_unibyte_string (chars_start, chars_len);
4101 hash_lookup (table, chars, &hash_code);
4102 hash_put (table, chars, color, hash_code);
4105 static Lisp_Object
4106 xpm_get_color_table_h (color_table, chars_start, chars_len)
4107 Lisp_Object color_table;
4108 const unsigned char *chars_start;
4109 int chars_len;
4111 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
4112 int i = hash_lookup (table, make_unibyte_string (chars_start, chars_len),
4113 NULL);
4115 return i >= 0 ? HASH_VALUE (table, i) : Qnil;
4118 enum xpm_color_key {
4119 XPM_COLOR_KEY_S,
4120 XPM_COLOR_KEY_M,
4121 XPM_COLOR_KEY_G4,
4122 XPM_COLOR_KEY_G,
4123 XPM_COLOR_KEY_C
4126 static const char xpm_color_key_strings[][4] = {"s", "m", "g4", "g", "c"};
4128 static int
4129 xpm_str_to_color_key (s)
4130 const char *s;
4132 int i;
4134 for (i = 0;
4135 i < sizeof xpm_color_key_strings / sizeof xpm_color_key_strings[0];
4136 i++)
4137 if (strcmp (xpm_color_key_strings[i], s) == 0)
4138 return i;
4139 return -1;
4142 static int
4143 xpm_load_image (f, img, contents, end)
4144 struct frame *f;
4145 struct image *img;
4146 const unsigned char *contents, *end;
4148 const unsigned char *s = contents, *beg, *str;
4149 unsigned char buffer[BUFSIZ];
4150 int width, height, x, y;
4151 int num_colors, chars_per_pixel;
4152 int len, LA1;
4153 void (*put_color_table) (Lisp_Object, const unsigned char *, int, Lisp_Object);
4154 Lisp_Object (*get_color_table) (Lisp_Object, const unsigned char *, int);
4155 Lisp_Object frame, color_symbols, color_table;
4156 int best_key, have_mask = 0;
4157 XImagePtr ximg = NULL, mask_img = NULL;
4159 #define match() \
4160 LA1 = xpm_scan (&s, end, &beg, &len)
4162 #define expect(TOKEN) \
4163 if (LA1 != (TOKEN)) \
4164 goto failure; \
4165 else \
4166 match ()
4168 #define expect_ident(IDENT) \
4169 if (LA1 == XPM_TK_IDENT \
4170 && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
4171 match (); \
4172 else \
4173 goto failure
4175 if (!(end - s >= 9 && memcmp (s, "/* XPM */", 9) == 0))
4176 goto failure;
4177 s += 9;
4178 match();
4179 expect_ident ("static");
4180 expect_ident ("char");
4181 expect ('*');
4182 expect (XPM_TK_IDENT);
4183 expect ('[');
4184 expect (']');
4185 expect ('=');
4186 expect ('{');
4187 expect (XPM_TK_STRING);
4188 if (len >= BUFSIZ)
4189 goto failure;
4190 memcpy (buffer, beg, len);
4191 buffer[len] = '\0';
4192 if (sscanf (buffer, "%d %d %d %d", &width, &height,
4193 &num_colors, &chars_per_pixel) != 4
4194 || width <= 0 || height <= 0
4195 || num_colors <= 0 || chars_per_pixel <= 0)
4196 goto failure;
4198 if (!check_image_size (f, width, height))
4200 image_error ("Invalid image size", Qnil, Qnil);
4201 goto failure;
4204 expect (',');
4206 XSETFRAME (frame, f);
4207 if (!NILP (Fxw_display_color_p (frame)))
4208 best_key = XPM_COLOR_KEY_C;
4209 else if (!NILP (Fx_display_grayscale_p (frame)))
4210 best_key = (XFASTINT (Fx_display_planes (frame)) > 2
4211 ? XPM_COLOR_KEY_G : XPM_COLOR_KEY_G4);
4212 else
4213 best_key = XPM_COLOR_KEY_M;
4215 color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL);
4216 if (chars_per_pixel == 1)
4217 color_table = xpm_make_color_table_v (&put_color_table,
4218 &get_color_table);
4219 else
4220 color_table = xpm_make_color_table_h (&put_color_table,
4221 &get_color_table);
4223 while (num_colors-- > 0)
4225 unsigned char *color, *max_color;
4226 int key, next_key, max_key = 0;
4227 Lisp_Object symbol_color = Qnil, color_val;
4228 XColor cdef;
4230 expect (XPM_TK_STRING);
4231 if (len <= chars_per_pixel || len >= BUFSIZ + chars_per_pixel)
4232 goto failure;
4233 memcpy (buffer, beg + chars_per_pixel, len - chars_per_pixel);
4234 buffer[len - chars_per_pixel] = '\0';
4236 str = strtok (buffer, " \t");
4237 if (str == NULL)
4238 goto failure;
4239 key = xpm_str_to_color_key (str);
4240 if (key < 0)
4241 goto failure;
4244 color = strtok (NULL, " \t");
4245 if (color == NULL)
4246 goto failure;
4248 while ((str = strtok (NULL, " \t")) != NULL)
4250 next_key = xpm_str_to_color_key (str);
4251 if (next_key >= 0)
4252 break;
4253 color[strlen (color)] = ' ';
4256 if (key == XPM_COLOR_KEY_S)
4258 if (NILP (symbol_color))
4259 symbol_color = build_string (color);
4261 else if (max_key < key && key <= best_key)
4263 max_key = key;
4264 max_color = color;
4266 key = next_key;
4268 while (str);
4270 color_val = Qnil;
4271 if (!NILP (color_symbols) && !NILP (symbol_color))
4273 Lisp_Object specified_color = Fassoc (symbol_color, color_symbols);
4275 if (CONSP (specified_color) && STRINGP (XCDR (specified_color)))
4277 if (xstrcasecmp (SDATA (XCDR (specified_color)), "None") == 0)
4278 color_val = Qt;
4279 else if (x_defined_color (f, SDATA (XCDR (specified_color)),
4280 &cdef, 0))
4281 color_val = make_number (cdef.pixel);
4284 if (NILP (color_val) && max_key > 0)
4286 if (xstrcasecmp (max_color, "None") == 0)
4287 color_val = Qt;
4288 else if (x_defined_color (f, max_color, &cdef, 0))
4289 color_val = make_number (cdef.pixel);
4291 if (!NILP (color_val))
4292 (*put_color_table) (color_table, beg, chars_per_pixel, color_val);
4294 expect (',');
4297 if (!x_create_x_image_and_pixmap (f, width, height, 0,
4298 &ximg, &img->pixmap)
4299 #ifndef HAVE_NS
4300 || !x_create_x_image_and_pixmap (f, width, height, 1,
4301 &mask_img, &img->mask)
4302 #endif
4305 image_error ("Out of memory (%s)", img->spec, Qnil);
4306 goto error;
4309 for (y = 0; y < height; y++)
4311 expect (XPM_TK_STRING);
4312 str = beg;
4313 if (len < width * chars_per_pixel)
4314 goto failure;
4315 for (x = 0; x < width; x++, str += chars_per_pixel)
4317 Lisp_Object color_val =
4318 (*get_color_table) (color_table, str, chars_per_pixel);
4320 XPutPixel (ximg, x, y,
4321 (INTEGERP (color_val) ? XINT (color_val)
4322 : FRAME_FOREGROUND_PIXEL (f)));
4323 #ifndef HAVE_NS
4324 XPutPixel (mask_img, x, y,
4325 (!EQ (color_val, Qt) ? PIX_MASK_DRAW
4326 : (have_mask = 1, PIX_MASK_RETAIN)));
4327 #else
4328 if (EQ(color_val, Qt))
4329 ns_set_alpha(ximg, x, y, 0);
4330 #endif
4332 if (y + 1 < height)
4333 expect (',');
4336 img->width = width;
4337 img->height = height;
4339 /* Maybe fill in the background field while we have ximg handy. */
4340 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
4341 IMAGE_BACKGROUND (img, f, ximg);
4343 x_put_x_image (f, ximg, img->pixmap, width, height);
4344 x_destroy_x_image (ximg);
4345 #ifndef HAVE_NS
4346 if (have_mask)
4348 /* Fill in the background_transparent field while we have the
4349 mask handy. */
4350 image_background_transparent (img, f, mask_img);
4352 x_put_x_image (f, mask_img, img->mask, width, height);
4353 x_destroy_x_image (mask_img);
4355 else
4357 x_destroy_x_image (mask_img);
4358 Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
4359 img->mask = NO_PIXMAP;
4361 #endif
4362 return 1;
4364 failure:
4365 image_error ("Invalid XPM file (%s)", img->spec, Qnil);
4366 error:
4367 x_destroy_x_image (ximg);
4368 x_destroy_x_image (mask_img);
4369 x_clear_image (f, img);
4370 return 0;
4372 #undef match
4373 #undef expect
4374 #undef expect_ident
4377 static int
4378 xpm_load (f, img)
4379 struct frame *f;
4380 struct image *img;
4382 int success_p = 0;
4383 Lisp_Object file_name;
4385 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4386 file_name = image_spec_value (img->spec, QCfile, NULL);
4387 if (STRINGP (file_name))
4389 Lisp_Object file;
4390 unsigned char *contents;
4391 int size;
4392 struct gcpro gcpro1;
4394 file = x_find_image_file (file_name);
4395 GCPRO1 (file);
4396 if (!STRINGP (file))
4398 image_error ("Cannot find image file `%s'", file_name, Qnil);
4399 UNGCPRO;
4400 return 0;
4403 contents = slurp_file (SDATA (file), &size);
4404 if (contents == NULL)
4406 image_error ("Error loading XPM image `%s'", img->spec, Qnil);
4407 UNGCPRO;
4408 return 0;
4411 success_p = xpm_load_image (f, img, contents, contents + size);
4412 xfree (contents);
4413 UNGCPRO;
4415 else
4417 Lisp_Object data;
4419 data = image_spec_value (img->spec, QCdata, NULL);
4420 success_p = xpm_load_image (f, img, SDATA (data),
4421 SDATA (data) + SBYTES (data));
4424 return success_p;
4427 #endif /* HAVE_NS && !HAVE_XPM */
4431 /***********************************************************************
4432 Color table
4433 ***********************************************************************/
4435 #ifdef COLOR_TABLE_SUPPORT
4437 /* An entry in the color table mapping an RGB color to a pixel color. */
4439 struct ct_color
4441 int r, g, b;
4442 unsigned long pixel;
4444 /* Next in color table collision list. */
4445 struct ct_color *next;
4448 /* The bucket vector size to use. Must be prime. */
4450 #define CT_SIZE 101
4452 /* Value is a hash of the RGB color given by R, G, and B. */
4454 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
4456 /* The color hash table. */
4458 struct ct_color **ct_table;
4460 /* Number of entries in the color table. */
4462 int ct_colors_allocated;
4464 /* Initialize the color table. */
4466 static void
4467 init_color_table ()
4469 int size = CT_SIZE * sizeof (*ct_table);
4470 ct_table = (struct ct_color **) xmalloc (size);
4471 bzero (ct_table, size);
4472 ct_colors_allocated = 0;
4476 /* Free memory associated with the color table. */
4478 static void
4479 free_color_table ()
4481 int i;
4482 struct ct_color *p, *next;
4484 for (i = 0; i < CT_SIZE; ++i)
4485 for (p = ct_table[i]; p; p = next)
4487 next = p->next;
4488 xfree (p);
4491 xfree (ct_table);
4492 ct_table = NULL;
4496 /* Value is a pixel color for RGB color R, G, B on frame F. If an
4497 entry for that color already is in the color table, return the
4498 pixel color of that entry. Otherwise, allocate a new color for R,
4499 G, B, and make an entry in the color table. */
4501 static unsigned long
4502 lookup_rgb_color (f, r, g, b)
4503 struct frame *f;
4504 int r, g, b;
4506 unsigned hash = CT_HASH_RGB (r, g, b);
4507 int i = hash % CT_SIZE;
4508 struct ct_color *p;
4509 Display_Info *dpyinfo;
4511 /* Handle TrueColor visuals specially, which improves performance by
4512 two orders of magnitude. Freeing colors on TrueColor visuals is
4513 a nop, and pixel colors specify RGB values directly. See also
4514 the Xlib spec, chapter 3.1. */
4515 dpyinfo = FRAME_X_DISPLAY_INFO (f);
4516 if (dpyinfo->red_bits > 0)
4518 unsigned long pr, pg, pb;
4520 /* Apply gamma-correction like normal color allocation does. */
4521 if (f->gamma)
4523 XColor color;
4524 color.red = r, color.green = g, color.blue = b;
4525 gamma_correct (f, &color);
4526 r = color.red, g = color.green, b = color.blue;
4529 /* Scale down RGB values to the visual's bits per RGB, and shift
4530 them to the right position in the pixel color. Note that the
4531 original RGB values are 16-bit values, as usual in X. */
4532 pr = (r >> (16 - dpyinfo->red_bits)) << dpyinfo->red_offset;
4533 pg = (g >> (16 - dpyinfo->green_bits)) << dpyinfo->green_offset;
4534 pb = (b >> (16 - dpyinfo->blue_bits)) << dpyinfo->blue_offset;
4536 /* Assemble the pixel color. */
4537 return pr | pg | pb;
4540 for (p = ct_table[i]; p; p = p->next)
4541 if (p->r == r && p->g == g && p->b == b)
4542 break;
4544 if (p == NULL)
4547 #ifdef HAVE_X_WINDOWS
4548 XColor color;
4549 Colormap cmap;
4550 int rc;
4552 color.red = r;
4553 color.green = g;
4554 color.blue = b;
4556 cmap = FRAME_X_COLORMAP (f);
4557 rc = x_alloc_nearest_color (f, cmap, &color);
4558 if (rc)
4560 ++ct_colors_allocated;
4561 p = (struct ct_color *) xmalloc (sizeof *p);
4562 p->r = r;
4563 p->g = g;
4564 p->b = b;
4565 p->pixel = color.pixel;
4566 p->next = ct_table[i];
4567 ct_table[i] = p;
4569 else
4570 return FRAME_FOREGROUND_PIXEL (f);
4572 #else
4573 COLORREF color;
4574 #ifdef HAVE_NTGUI
4575 color = PALETTERGB (r, g, b);
4576 #else
4577 color = RGB_TO_ULONG (r, g, b);
4578 #endif /* HAVE_NTGUI */
4579 ++ct_colors_allocated;
4580 p = (struct ct_color *) xmalloc (sizeof *p);
4581 p->r = r;
4582 p->g = g;
4583 p->b = b;
4584 p->pixel = color;
4585 p->next = ct_table[i];
4586 ct_table[i] = p;
4587 #endif /* HAVE_X_WINDOWS */
4591 return p->pixel;
4595 /* Look up pixel color PIXEL which is used on frame F in the color
4596 table. If not already present, allocate it. Value is PIXEL. */
4598 static unsigned long
4599 lookup_pixel_color (f, pixel)
4600 struct frame *f;
4601 unsigned long pixel;
4603 int i = pixel % CT_SIZE;
4604 struct ct_color *p;
4606 for (p = ct_table[i]; p; p = p->next)
4607 if (p->pixel == pixel)
4608 break;
4610 if (p == NULL)
4612 XColor color;
4613 Colormap cmap;
4614 int rc;
4616 #ifdef HAVE_X_WINDOWS
4617 cmap = FRAME_X_COLORMAP (f);
4618 color.pixel = pixel;
4619 x_query_color (f, &color);
4620 rc = x_alloc_nearest_color (f, cmap, &color);
4621 #else
4622 BLOCK_INPUT;
4623 cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f));
4624 color.pixel = pixel;
4625 XQueryColor (NULL, cmap, &color);
4626 rc = x_alloc_nearest_color (f, cmap, &color);
4627 UNBLOCK_INPUT;
4628 #endif /* HAVE_X_WINDOWS */
4630 if (rc)
4632 ++ct_colors_allocated;
4634 p = (struct ct_color *) xmalloc (sizeof *p);
4635 p->r = color.red;
4636 p->g = color.green;
4637 p->b = color.blue;
4638 p->pixel = pixel;
4639 p->next = ct_table[i];
4640 ct_table[i] = p;
4642 else
4643 return FRAME_FOREGROUND_PIXEL (f);
4645 return p->pixel;
4649 /* Value is a vector of all pixel colors contained in the color table,
4650 allocated via xmalloc. Set *N to the number of colors. */
4652 static unsigned long *
4653 colors_in_color_table (n)
4654 int *n;
4656 int i, j;
4657 struct ct_color *p;
4658 unsigned long *colors;
4660 if (ct_colors_allocated == 0)
4662 *n = 0;
4663 colors = NULL;
4665 else
4667 colors = (unsigned long *) xmalloc (ct_colors_allocated
4668 * sizeof *colors);
4669 *n = ct_colors_allocated;
4671 for (i = j = 0; i < CT_SIZE; ++i)
4672 for (p = ct_table[i]; p; p = p->next)
4673 colors[j++] = p->pixel;
4676 return colors;
4679 #else /* COLOR_TABLE_SUPPORT */
4681 static unsigned long
4682 lookup_rgb_color (f, r, g, b)
4683 struct frame *f;
4684 int r, g, b;
4686 unsigned long pixel;
4688 #ifdef HAVE_NTGUI
4689 pixel = PALETTERGB (r >> 8, g >> 8, b >> 8);
4690 #endif /* HAVE_NTGUI */
4692 #ifdef HAVE_NS
4693 pixel = RGB_TO_ULONG (r >> 8, g >> 8, b >> 8);
4694 #endif /* HAVE_NS */
4695 return pixel;
4698 static void
4699 init_color_table ()
4702 #endif /* COLOR_TABLE_SUPPORT */
4705 /***********************************************************************
4706 Algorithms
4707 ***********************************************************************/
4709 static XColor *x_to_xcolors P_ ((struct frame *, struct image *, int));
4710 static void x_from_xcolors P_ ((struct frame *, struct image *, XColor *));
4711 static void x_detect_edges P_ ((struct frame *, struct image *, int[9], int));
4713 #ifdef HAVE_NTGUI
4714 static void XPutPixel (XImagePtr , int, int, COLORREF);
4715 #endif /* HAVE_NTGUI */
4717 /* Non-zero means draw a cross on images having `:conversion
4718 disabled'. */
4720 int cross_disabled_images;
4722 /* Edge detection matrices for different edge-detection
4723 strategies. */
4725 static int emboss_matrix[9] = {
4726 /* x - 1 x x + 1 */
4727 2, -1, 0, /* y - 1 */
4728 -1, 0, 1, /* y */
4729 0, 1, -2 /* y + 1 */
4732 static int laplace_matrix[9] = {
4733 /* x - 1 x x + 1 */
4734 1, 0, 0, /* y - 1 */
4735 0, 0, 0, /* y */
4736 0, 0, -1 /* y + 1 */
4739 /* Value is the intensity of the color whose red/green/blue values
4740 are R, G, and B. */
4742 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
4745 /* On frame F, return an array of XColor structures describing image
4746 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
4747 non-zero means also fill the red/green/blue members of the XColor
4748 structures. Value is a pointer to the array of XColors structures,
4749 allocated with xmalloc; it must be freed by the caller. */
4751 static XColor *
4752 x_to_xcolors (f, img, rgb_p)
4753 struct frame *f;
4754 struct image *img;
4755 int rgb_p;
4757 int x, y;
4758 XColor *colors, *p;
4759 XImagePtr_or_DC ximg;
4760 #ifdef HAVE_NTGUI
4761 HDC hdc;
4762 HGDIOBJ prev;
4763 #endif /* HAVE_NTGUI */
4765 colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors);
4767 #ifndef HAVE_NTGUI
4768 /* Get the X image IMG->pixmap. */
4769 ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
4770 0, 0, img->width, img->height, ~0, ZPixmap);
4771 #else
4772 /* Load the image into a memory device context. */
4773 hdc = get_frame_dc (f);
4774 ximg = CreateCompatibleDC (hdc);
4775 release_frame_dc (f, hdc);
4776 prev = SelectObject (ximg, img->pixmap);
4777 #endif /* HAVE_NTGUI */
4779 /* Fill the `pixel' members of the XColor array. I wished there
4780 were an easy and portable way to circumvent XGetPixel. */
4781 p = colors;
4782 for (y = 0; y < img->height; ++y)
4784 XColor *row = p;
4786 #ifdef HAVE_X_WINDOWS
4787 for (x = 0; x < img->width; ++x, ++p)
4788 p->pixel = XGetPixel (ximg, x, y);
4789 if (rgb_p)
4790 x_query_colors (f, row, img->width);
4792 #else
4794 for (x = 0; x < img->width; ++x, ++p)
4796 /* W32_TODO: palette support needed here? */
4797 p->pixel = GET_PIXEL (ximg, x, y);
4798 if (rgb_p)
4800 #if defined (HAVE_NS)
4801 p->red = RED16_FROM_ULONG (p->pixel);
4802 p->green = GREEN16_FROM_ULONG (p->pixel);
4803 p->blue = BLUE16_FROM_ULONG (p->pixel);
4804 #endif /* HAVE_NS */
4805 #ifdef HAVE_NTGUI
4806 p->red = 256 * GetRValue (p->pixel);
4807 p->green = 256 * GetGValue (p->pixel);
4808 p->blue = 256 * GetBValue (p->pixel);
4809 #endif /* HAVE_NTGUI */
4812 #endif /* HAVE_X_WINDOWS */
4815 Destroy_Image (ximg, prev);
4817 return colors;
4820 #ifdef HAVE_NTGUI
4822 /* Put a pixel of COLOR at position X, Y in XIMG. XIMG must have been
4823 created with CreateDIBSection, with the pointer to the bit values
4824 stored in ximg->data. */
4826 static void
4827 XPutPixel (ximg, x, y, color)
4828 XImagePtr ximg;
4829 int x, y;
4830 COLORREF color;
4832 int width = ximg->info.bmiHeader.biWidth;
4833 int height = ximg->info.bmiHeader.biHeight;
4834 unsigned char * pixel;
4836 /* True color images. */
4837 if (ximg->info.bmiHeader.biBitCount == 24)
4839 int rowbytes = width * 3;
4840 /* Ensure scanlines are aligned on 4 byte boundaries. */
4841 if (rowbytes % 4)
4842 rowbytes += 4 - (rowbytes % 4);
4844 pixel = ximg->data + y * rowbytes + x * 3;
4845 /* Windows bitmaps are in BGR order. */
4846 *pixel = GetBValue (color);
4847 *(pixel + 1) = GetGValue (color);
4848 *(pixel + 2) = GetRValue (color);
4850 /* Monochrome images. */
4851 else if (ximg->info.bmiHeader.biBitCount == 1)
4853 int rowbytes = width / 8;
4854 /* Ensure scanlines are aligned on 4 byte boundaries. */
4855 if (rowbytes % 4)
4856 rowbytes += 4 - (rowbytes % 4);
4857 pixel = ximg->data + y * rowbytes + x / 8;
4858 /* Filter out palette info. */
4859 if (color & 0x00ffffff)
4860 *pixel = *pixel | (1 << x % 8);
4861 else
4862 *pixel = *pixel & ~(1 << x % 8);
4864 else
4865 image_error ("XPutPixel: palette image not supported", Qnil, Qnil);
4868 #endif /* HAVE_NTGUI */
4870 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
4871 RGB members are set. F is the frame on which this all happens.
4872 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
4874 static void
4875 x_from_xcolors (f, img, colors)
4876 struct frame *f;
4877 struct image *img;
4878 XColor *colors;
4880 int x, y;
4881 XImagePtr oimg = NULL;
4882 Pixmap pixmap;
4883 XColor *p;
4885 init_color_table ();
4887 x_create_x_image_and_pixmap (f, img->width, img->height, 0,
4888 &oimg, &pixmap);
4889 p = colors;
4890 for (y = 0; y < img->height; ++y)
4891 for (x = 0; x < img->width; ++x, ++p)
4893 unsigned long pixel;
4894 pixel = lookup_rgb_color (f, p->red, p->green, p->blue);
4895 XPutPixel (oimg, x, y, pixel);
4898 xfree (colors);
4899 x_clear_image_1 (f, img, 1, 0, 1);
4901 x_put_x_image (f, oimg, pixmap, img->width, img->height);
4902 x_destroy_x_image (oimg);
4903 img->pixmap = pixmap;
4904 #ifdef COLOR_TABLE_SUPPORT
4905 img->colors = colors_in_color_table (&img->ncolors);
4906 free_color_table ();
4907 #endif /* COLOR_TABLE_SUPPORT */
4911 /* On frame F, perform edge-detection on image IMG.
4913 MATRIX is a nine-element array specifying the transformation
4914 matrix. See emboss_matrix for an example.
4916 COLOR_ADJUST is a color adjustment added to each pixel of the
4917 outgoing image. */
4919 static void
4920 x_detect_edges (f, img, matrix, color_adjust)
4921 struct frame *f;
4922 struct image *img;
4923 int matrix[9], color_adjust;
4925 XColor *colors = x_to_xcolors (f, img, 1);
4926 XColor *new, *p;
4927 int x, y, i, sum;
4929 for (i = sum = 0; i < 9; ++i)
4930 sum += eabs (matrix[i]);
4932 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
4934 new = (XColor *) xmalloc (img->width * img->height * sizeof *new);
4936 for (y = 0; y < img->height; ++y)
4938 p = COLOR (new, 0, y);
4939 p->red = p->green = p->blue = 0xffff/2;
4940 p = COLOR (new, img->width - 1, y);
4941 p->red = p->green = p->blue = 0xffff/2;
4944 for (x = 1; x < img->width - 1; ++x)
4946 p = COLOR (new, x, 0);
4947 p->red = p->green = p->blue = 0xffff/2;
4948 p = COLOR (new, x, img->height - 1);
4949 p->red = p->green = p->blue = 0xffff/2;
4952 for (y = 1; y < img->height - 1; ++y)
4954 p = COLOR (new, 1, y);
4956 for (x = 1; x < img->width - 1; ++x, ++p)
4958 int r, g, b, y1, x1;
4960 r = g = b = i = 0;
4961 for (y1 = y - 1; y1 < y + 2; ++y1)
4962 for (x1 = x - 1; x1 < x + 2; ++x1, ++i)
4963 if (matrix[i])
4965 XColor *t = COLOR (colors, x1, y1);
4966 r += matrix[i] * t->red;
4967 g += matrix[i] * t->green;
4968 b += matrix[i] * t->blue;
4971 r = (r / sum + color_adjust) & 0xffff;
4972 g = (g / sum + color_adjust) & 0xffff;
4973 b = (b / sum + color_adjust) & 0xffff;
4974 p->red = p->green = p->blue = COLOR_INTENSITY (r, g, b);
4978 xfree (colors);
4979 x_from_xcolors (f, img, new);
4981 #undef COLOR
4985 /* Perform the pre-defined `emboss' edge-detection on image IMG
4986 on frame F. */
4988 static void
4989 x_emboss (f, img)
4990 struct frame *f;
4991 struct image *img;
4993 x_detect_edges (f, img, emboss_matrix, 0xffff / 2);
4997 /* Transform image IMG which is used on frame F with a Laplace
4998 edge-detection algorithm. The result is an image that can be used
4999 to draw disabled buttons, for example. */
5001 static void
5002 x_laplace (f, img)
5003 struct frame *f;
5004 struct image *img;
5006 x_detect_edges (f, img, laplace_matrix, 45000);
5010 /* Perform edge-detection on image IMG on frame F, with specified
5011 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
5013 MATRIX must be either
5015 - a list of at least 9 numbers in row-major form
5016 - a vector of at least 9 numbers
5018 COLOR_ADJUST nil means use a default; otherwise it must be a
5019 number. */
5021 static void
5022 x_edge_detection (f, img, matrix, color_adjust)
5023 struct frame *f;
5024 struct image *img;
5025 Lisp_Object matrix, color_adjust;
5027 int i = 0;
5028 int trans[9];
5030 if (CONSP (matrix))
5032 for (i = 0;
5033 i < 9 && CONSP (matrix) && NUMBERP (XCAR (matrix));
5034 ++i, matrix = XCDR (matrix))
5035 trans[i] = XFLOATINT (XCAR (matrix));
5037 else if (VECTORP (matrix) && ASIZE (matrix) >= 9)
5039 for (i = 0; i < 9 && NUMBERP (AREF (matrix, i)); ++i)
5040 trans[i] = XFLOATINT (AREF (matrix, i));
5043 if (NILP (color_adjust))
5044 color_adjust = make_number (0xffff / 2);
5046 if (i == 9 && NUMBERP (color_adjust))
5047 x_detect_edges (f, img, trans, (int) XFLOATINT (color_adjust));
5051 /* Transform image IMG on frame F so that it looks disabled. */
5053 static void
5054 x_disable_image (f, img)
5055 struct frame *f;
5056 struct image *img;
5058 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
5059 #ifdef HAVE_NTGUI
5060 int n_planes = dpyinfo->n_planes * dpyinfo->n_cbits;
5061 #else
5062 int n_planes = dpyinfo->n_planes;
5063 #endif /* HAVE_NTGUI */
5065 if (n_planes >= 2)
5067 /* Color (or grayscale). Convert to gray, and equalize. Just
5068 drawing such images with a stipple can look very odd, so
5069 we're using this method instead. */
5070 XColor *colors = x_to_xcolors (f, img, 1);
5071 XColor *p, *end;
5072 const int h = 15000;
5073 const int l = 30000;
5075 for (p = colors, end = colors + img->width * img->height;
5076 p < end;
5077 ++p)
5079 int i = COLOR_INTENSITY (p->red, p->green, p->blue);
5080 int i2 = (0xffff - h - l) * i / 0xffff + l;
5081 p->red = p->green = p->blue = i2;
5084 x_from_xcolors (f, img, colors);
5087 /* Draw a cross over the disabled image, if we must or if we
5088 should. */
5089 if (n_planes < 2 || cross_disabled_images)
5091 #ifndef HAVE_NTGUI
5092 Display *dpy = FRAME_X_DISPLAY (f);
5093 GC gc;
5095 #ifndef HAVE_NS //TODO: NS support, however this not needed for toolbars
5097 #define MaskForeground(f) WHITE_PIX_DEFAULT (f)
5099 gc = XCreateGC (dpy, img->pixmap, 0, NULL);
5100 XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f));
5101 XDrawLine (dpy, img->pixmap, gc, 0, 0,
5102 img->width - 1, img->height - 1);
5103 XDrawLine (dpy, img->pixmap, gc, 0, img->height - 1,
5104 img->width - 1, 0);
5105 XFreeGC (dpy, gc);
5107 if (img->mask)
5109 gc = XCreateGC (dpy, img->mask, 0, NULL);
5110 XSetForeground (dpy, gc, MaskForeground (f));
5111 XDrawLine (dpy, img->mask, gc, 0, 0,
5112 img->width - 1, img->height - 1);
5113 XDrawLine (dpy, img->mask, gc, 0, img->height - 1,
5114 img->width - 1, 0);
5115 XFreeGC (dpy, gc);
5117 #endif /* !HAVE_NS */
5118 #else
5119 HDC hdc, bmpdc;
5120 HGDIOBJ prev;
5122 hdc = get_frame_dc (f);
5123 bmpdc = CreateCompatibleDC (hdc);
5124 release_frame_dc (f, hdc);
5126 prev = SelectObject (bmpdc, img->pixmap);
5128 SetTextColor (bmpdc, BLACK_PIX_DEFAULT (f));
5129 MoveToEx (bmpdc, 0, 0, NULL);
5130 LineTo (bmpdc, img->width - 1, img->height - 1);
5131 MoveToEx (bmpdc, 0, img->height - 1, NULL);
5132 LineTo (bmpdc, img->width - 1, 0);
5134 if (img->mask)
5136 SelectObject (bmpdc, img->mask);
5137 SetTextColor (bmpdc, WHITE_PIX_DEFAULT (f));
5138 MoveToEx (bmpdc, 0, 0, NULL);
5139 LineTo (bmpdc, img->width - 1, img->height - 1);
5140 MoveToEx (bmpdc, 0, img->height - 1, NULL);
5141 LineTo (bmpdc, img->width - 1, 0);
5143 SelectObject (bmpdc, prev);
5144 DeleteDC (bmpdc);
5145 #endif /* HAVE_NTGUI */
5150 /* Build a mask for image IMG which is used on frame F. FILE is the
5151 name of an image file, for error messages. HOW determines how to
5152 determine the background color of IMG. If it is a list '(R G B)',
5153 with R, G, and B being integers >= 0, take that as the color of the
5154 background. Otherwise, determine the background color of IMG
5155 heuristically. Value is non-zero if successful. */
5157 static int
5158 x_build_heuristic_mask (f, img, how)
5159 struct frame *f;
5160 struct image *img;
5161 Lisp_Object how;
5163 XImagePtr_or_DC ximg;
5164 #ifndef HAVE_NTGUI
5165 XImagePtr mask_img;
5166 #else
5167 HDC frame_dc;
5168 HGDIOBJ prev;
5169 char *mask_img;
5170 int row_width;
5171 #endif /* HAVE_NTGUI */
5172 int x, y, rc, use_img_background;
5173 unsigned long bg = 0;
5175 if (img->mask)
5177 Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
5178 img->mask = NO_PIXMAP;
5179 img->background_transparent_valid = 0;
5182 #ifndef HAVE_NTGUI
5183 #ifndef HAVE_NS
5184 /* Create an image and pixmap serving as mask. */
5185 rc = x_create_x_image_and_pixmap (f, img->width, img->height, 1,
5186 &mask_img, &img->mask);
5187 if (!rc)
5188 return 0;
5189 #endif /* !HAVE_NS */
5191 /* Get the X image of IMG->pixmap. */
5192 ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap, 0, 0,
5193 img->width, img->height,
5194 ~0, ZPixmap);
5195 #else
5196 /* Create the bit array serving as mask. */
5197 row_width = (img->width + 7) / 8;
5198 mask_img = xmalloc (row_width * img->height);
5199 bzero (mask_img, row_width * img->height);
5201 /* Create a memory device context for IMG->pixmap. */
5202 frame_dc = get_frame_dc (f);
5203 ximg = CreateCompatibleDC (frame_dc);
5204 release_frame_dc (f, frame_dc);
5205 prev = SelectObject (ximg, img->pixmap);
5206 #endif /* HAVE_NTGUI */
5208 /* Determine the background color of ximg. If HOW is `(R G B)'
5209 take that as color. Otherwise, use the image's background color. */
5210 use_img_background = 1;
5212 if (CONSP (how))
5214 int rgb[3], i;
5216 for (i = 0; i < 3 && CONSP (how) && NATNUMP (XCAR (how)); ++i)
5218 rgb[i] = XFASTINT (XCAR (how)) & 0xffff;
5219 how = XCDR (how);
5222 if (i == 3 && NILP (how))
5224 char color_name[30];
5225 sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]);
5226 bg = (
5227 #ifdef HAVE_NTGUI
5228 0x00ffffff & /* Filter out palette info. */
5229 #endif /* HAVE_NTGUI */
5230 x_alloc_image_color (f, img, build_string (color_name), 0));
5231 use_img_background = 0;
5235 if (use_img_background)
5236 bg = four_corners_best (ximg, img->corners, img->width, img->height);
5238 /* Set all bits in mask_img to 1 whose color in ximg is different
5239 from the background color bg. */
5240 #ifndef HAVE_NTGUI
5241 for (y = 0; y < img->height; ++y)
5242 for (x = 0; x < img->width; ++x)
5243 #ifndef HAVE_NS
5244 XPutPixel (mask_img, x, y, (XGetPixel (ximg, x, y) != bg
5245 ? PIX_MASK_DRAW : PIX_MASK_RETAIN));
5246 #else
5247 if (XGetPixel (ximg, x, y) == bg)
5248 ns_set_alpha(ximg, x, y, 0);
5249 #endif /* HAVE_NS */
5250 #ifndef HAVE_NS
5251 /* Fill in the background_transparent field while we have the mask handy. */
5252 image_background_transparent (img, f, mask_img);
5254 /* Put mask_img into img->mask. */
5255 x_put_x_image (f, mask_img, img->mask, img->width, img->height);
5256 x_destroy_x_image (mask_img);
5257 #endif /* !HAVE_NS */
5258 #else
5259 for (y = 0; y < img->height; ++y)
5260 for (x = 0; x < img->width; ++x)
5262 COLORREF p = GetPixel (ximg, x, y);
5263 if (p != bg)
5264 mask_img[y * row_width + x / 8] |= 1 << (x % 8);
5267 /* Create the mask image. */
5268 img->mask = w32_create_pixmap_from_bitmap_data (img->width, img->height,
5269 mask_img);
5270 /* Fill in the background_transparent field while we have the mask handy. */
5271 SelectObject (ximg, img->mask);
5272 image_background_transparent (img, f, ximg);
5274 /* Was: x_destroy_x_image ((XImagePtr )mask_img); which seems bogus ++kfs */
5275 xfree (mask_img);
5276 #endif /* HAVE_NTGUI */
5278 Destroy_Image (ximg, prev);
5280 return 1;
5284 /***********************************************************************
5285 PBM (mono, gray, color)
5286 ***********************************************************************/
5288 static int pbm_image_p P_ ((Lisp_Object object));
5289 static int pbm_load P_ ((struct frame *f, struct image *img));
5290 static int pbm_scan_number P_ ((unsigned char **, unsigned char *));
5292 /* The symbol `pbm' identifying images of this type. */
5294 Lisp_Object Qpbm;
5296 /* Indices of image specification fields in gs_format, below. */
5298 enum pbm_keyword_index
5300 PBM_TYPE,
5301 PBM_FILE,
5302 PBM_DATA,
5303 PBM_ASCENT,
5304 PBM_MARGIN,
5305 PBM_RELIEF,
5306 PBM_ALGORITHM,
5307 PBM_HEURISTIC_MASK,
5308 PBM_MASK,
5309 PBM_FOREGROUND,
5310 PBM_BACKGROUND,
5311 PBM_LAST
5314 /* Vector of image_keyword structures describing the format
5315 of valid user-defined image specifications. */
5317 static struct image_keyword pbm_format[PBM_LAST] =
5319 {":type", IMAGE_SYMBOL_VALUE, 1},
5320 {":file", IMAGE_STRING_VALUE, 0},
5321 {":data", IMAGE_STRING_VALUE, 0},
5322 {":ascent", IMAGE_ASCENT_VALUE, 0},
5323 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
5324 {":relief", IMAGE_INTEGER_VALUE, 0},
5325 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5326 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5327 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5328 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
5329 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
5332 /* Structure describing the image type `pbm'. */
5334 static struct image_type pbm_type =
5336 &Qpbm,
5337 pbm_image_p,
5338 pbm_load,
5339 x_clear_image,
5340 NULL
5344 /* Return non-zero if OBJECT is a valid PBM image specification. */
5346 static int
5347 pbm_image_p (object)
5348 Lisp_Object object;
5350 struct image_keyword fmt[PBM_LAST];
5352 bcopy (pbm_format, fmt, sizeof fmt);
5354 if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm))
5355 return 0;
5357 /* Must specify either :data or :file. */
5358 return fmt[PBM_DATA].count + fmt[PBM_FILE].count == 1;
5362 /* Scan a decimal number from *S and return it. Advance *S while
5363 reading the number. END is the end of the string. Value is -1 at
5364 end of input. */
5366 static int
5367 pbm_scan_number (s, end)
5368 unsigned char **s, *end;
5370 int c = 0, val = -1;
5372 while (*s < end)
5374 /* Skip white-space. */
5375 while (*s < end && (c = *(*s)++, isspace (c)))
5378 if (c == '#')
5380 /* Skip comment to end of line. */
5381 while (*s < end && (c = *(*s)++, c != '\n'))
5384 else if (isdigit (c))
5386 /* Read decimal number. */
5387 val = c - '0';
5388 while (*s < end && (c = *(*s)++, isdigit (c)))
5389 val = 10 * val + c - '0';
5390 break;
5392 else
5393 break;
5396 return val;
5400 #ifdef HAVE_NTGUI
5401 #if 0 /* Unused. ++kfs */
5403 /* Read FILE into memory. Value is a pointer to a buffer allocated
5404 with xmalloc holding FILE's contents. Value is null if an error
5405 occurred. *SIZE is set to the size of the file. */
5407 static char *
5408 pbm_read_file (file, size)
5409 Lisp_Object file;
5410 int *size;
5412 FILE *fp = NULL;
5413 char *buf = NULL;
5414 struct stat st;
5416 if (stat (SDATA (file), &st) == 0
5417 && (fp = fopen (SDATA (file), "rb")) != NULL
5418 && (buf = (char *) xmalloc (st.st_size),
5419 fread (buf, 1, st.st_size, fp) == st.st_size))
5421 *size = st.st_size;
5422 fclose (fp);
5424 else
5426 if (fp)
5427 fclose (fp);
5428 if (buf)
5430 xfree (buf);
5431 buf = NULL;
5435 return buf;
5437 #endif
5438 #endif /* HAVE_NTGUI */
5440 /* Load PBM image IMG for use on frame F. */
5442 static int
5443 pbm_load (f, img)
5444 struct frame *f;
5445 struct image *img;
5447 int raw_p, x, y;
5448 int width, height, max_color_idx = 0;
5449 XImagePtr ximg;
5450 Lisp_Object file, specified_file;
5451 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
5452 struct gcpro gcpro1;
5453 unsigned char *contents = NULL;
5454 unsigned char *end, *p;
5455 int size;
5457 specified_file = image_spec_value (img->spec, QCfile, NULL);
5458 file = Qnil;
5459 GCPRO1 (file);
5461 if (STRINGP (specified_file))
5463 file = x_find_image_file (specified_file);
5464 if (!STRINGP (file))
5466 image_error ("Cannot find image file `%s'", specified_file, Qnil);
5467 UNGCPRO;
5468 return 0;
5471 contents = slurp_file (SDATA (file), &size);
5472 if (contents == NULL)
5474 image_error ("Error reading `%s'", file, Qnil);
5475 UNGCPRO;
5476 return 0;
5479 p = contents;
5480 end = contents + size;
5482 else
5484 Lisp_Object data;
5485 data = image_spec_value (img->spec, QCdata, NULL);
5486 p = SDATA (data);
5487 end = p + SBYTES (data);
5490 /* Check magic number. */
5491 if (end - p < 2 || *p++ != 'P')
5493 image_error ("Not a PBM image: `%s'", img->spec, Qnil);
5494 error:
5495 xfree (contents);
5496 UNGCPRO;
5497 return 0;
5500 switch (*p++)
5502 case '1':
5503 raw_p = 0, type = PBM_MONO;
5504 break;
5506 case '2':
5507 raw_p = 0, type = PBM_GRAY;
5508 break;
5510 case '3':
5511 raw_p = 0, type = PBM_COLOR;
5512 break;
5514 case '4':
5515 raw_p = 1, type = PBM_MONO;
5516 break;
5518 case '5':
5519 raw_p = 1, type = PBM_GRAY;
5520 break;
5522 case '6':
5523 raw_p = 1, type = PBM_COLOR;
5524 break;
5526 default:
5527 image_error ("Not a PBM image: `%s'", img->spec, Qnil);
5528 goto error;
5531 /* Read width, height, maximum color-component. Characters
5532 starting with `#' up to the end of a line are ignored. */
5533 width = pbm_scan_number (&p, end);
5534 height = pbm_scan_number (&p, end);
5536 if (type != PBM_MONO)
5538 max_color_idx = pbm_scan_number (&p, end);
5539 if (max_color_idx > 65535 || max_color_idx < 0)
5541 image_error ("Unsupported maximum PBM color value", Qnil, Qnil);
5542 goto error;
5546 if (!check_image_size (f, width, height))
5548 image_error ("Invalid image size", Qnil, Qnil);
5549 goto error;
5552 if (!x_create_x_image_and_pixmap (f, width, height, 0,
5553 &ximg, &img->pixmap))
5554 goto error;
5556 /* Initialize the color hash table. */
5557 init_color_table ();
5559 if (type == PBM_MONO)
5561 int c = 0, g;
5562 struct image_keyword fmt[PBM_LAST];
5563 unsigned long fg = FRAME_FOREGROUND_PIXEL (f);
5564 unsigned long bg = FRAME_BACKGROUND_PIXEL (f);
5566 /* Parse the image specification. */
5567 bcopy (pbm_format, fmt, sizeof fmt);
5568 parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm);
5570 /* Get foreground and background colors, maybe allocate colors. */
5571 if (fmt[PBM_FOREGROUND].count
5572 && STRINGP (fmt[PBM_FOREGROUND].value))
5573 fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg);
5574 if (fmt[PBM_BACKGROUND].count
5575 && STRINGP (fmt[PBM_BACKGROUND].value))
5577 bg = x_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg);
5578 img->background = bg;
5579 img->background_valid = 1;
5582 for (y = 0; y < height; ++y)
5583 for (x = 0; x < width; ++x)
5585 if (raw_p)
5587 if ((x & 7) == 0)
5589 if (p >= end)
5591 x_destroy_x_image (ximg);
5592 x_clear_image (f, img);
5593 image_error ("Invalid image size in image `%s'",
5594 img->spec, Qnil);
5595 goto error;
5597 c = *p++;
5599 g = c & 0x80;
5600 c <<= 1;
5602 else
5603 g = pbm_scan_number (&p, end);
5605 XPutPixel (ximg, x, y, g ? fg : bg);
5608 else
5610 int expected_size = height * width;
5611 if (max_color_idx > 255)
5612 expected_size *= 2;
5613 if (type == PBM_COLOR)
5614 expected_size *= 3;
5616 if (raw_p && p + expected_size > end)
5618 x_destroy_x_image (ximg);
5619 x_clear_image (f, img);
5620 image_error ("Invalid image size in image `%s'",
5621 img->spec, Qnil);
5622 goto error;
5625 for (y = 0; y < height; ++y)
5626 for (x = 0; x < width; ++x)
5628 int r, g, b;
5630 if (type == PBM_GRAY && raw_p)
5632 r = g = b = *p++;
5633 if (max_color_idx > 255)
5634 r = g = b = r * 256 + *p++;
5636 else if (type == PBM_GRAY)
5637 r = g = b = pbm_scan_number (&p, end);
5638 else if (raw_p)
5640 r = *p++;
5641 if (max_color_idx > 255)
5642 r = r * 256 + *p++;
5643 g = *p++;
5644 if (max_color_idx > 255)
5645 g = g * 256 + *p++;
5646 b = *p++;
5647 if (max_color_idx > 255)
5648 b = b * 256 + *p++;
5650 else
5652 r = pbm_scan_number (&p, end);
5653 g = pbm_scan_number (&p, end);
5654 b = pbm_scan_number (&p, end);
5657 if (r < 0 || g < 0 || b < 0)
5659 x_destroy_x_image (ximg);
5660 image_error ("Invalid pixel value in image `%s'",
5661 img->spec, Qnil);
5662 goto error;
5665 /* RGB values are now in the range 0..max_color_idx.
5666 Scale this to the range 0..0xffff supported by X. */
5667 r = (double) r * 65535 / max_color_idx;
5668 g = (double) g * 65535 / max_color_idx;
5669 b = (double) b * 65535 / max_color_idx;
5670 XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
5674 #ifdef COLOR_TABLE_SUPPORT
5675 /* Store in IMG->colors the colors allocated for the image, and
5676 free the color table. */
5677 img->colors = colors_in_color_table (&img->ncolors);
5678 free_color_table ();
5679 #endif /* COLOR_TABLE_SUPPORT */
5681 img->width = width;
5682 img->height = height;
5684 /* Maybe fill in the background field while we have ximg handy. */
5686 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
5687 /* Casting avoids a GCC warning. */
5688 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
5690 /* Put the image into a pixmap. */
5691 x_put_x_image (f, ximg, img->pixmap, width, height);
5692 x_destroy_x_image (ximg);
5694 /* X and W32 versions did it here, MAC version above. ++kfs
5695 img->width = width;
5696 img->height = height; */
5698 UNGCPRO;
5699 xfree (contents);
5700 return 1;
5704 /***********************************************************************
5706 ***********************************************************************/
5708 #if defined (HAVE_PNG) || defined (HAVE_NS)
5710 /* Function prototypes. */
5712 static int png_image_p P_ ((Lisp_Object object));
5713 static int png_load P_ ((struct frame *f, struct image *img));
5715 /* The symbol `png' identifying images of this type. */
5717 Lisp_Object Qpng;
5719 /* Indices of image specification fields in png_format, below. */
5721 enum png_keyword_index
5723 PNG_TYPE,
5724 PNG_DATA,
5725 PNG_FILE,
5726 PNG_ASCENT,
5727 PNG_MARGIN,
5728 PNG_RELIEF,
5729 PNG_ALGORITHM,
5730 PNG_HEURISTIC_MASK,
5731 PNG_MASK,
5732 PNG_BACKGROUND,
5733 PNG_LAST
5736 /* Vector of image_keyword structures describing the format
5737 of valid user-defined image specifications. */
5739 static struct image_keyword png_format[PNG_LAST] =
5741 {":type", IMAGE_SYMBOL_VALUE, 1},
5742 {":data", IMAGE_STRING_VALUE, 0},
5743 {":file", IMAGE_STRING_VALUE, 0},
5744 {":ascent", IMAGE_ASCENT_VALUE, 0},
5745 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
5746 {":relief", IMAGE_INTEGER_VALUE, 0},
5747 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5748 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5749 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5750 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
5753 /* Structure describing the image type `png'. */
5755 static struct image_type png_type =
5757 &Qpng,
5758 png_image_p,
5759 png_load,
5760 x_clear_image,
5761 NULL
5764 /* Return non-zero if OBJECT is a valid PNG image specification. */
5766 static int
5767 png_image_p (object)
5768 Lisp_Object object;
5770 struct image_keyword fmt[PNG_LAST];
5771 bcopy (png_format, fmt, sizeof fmt);
5773 if (!parse_image_spec (object, fmt, PNG_LAST, Qpng))
5774 return 0;
5776 /* Must specify either the :data or :file keyword. */
5777 return fmt[PNG_FILE].count + fmt[PNG_DATA].count == 1;
5780 #endif /* HAVE_PNG || HAVE_NS */
5783 #ifdef HAVE_PNG
5785 #if defined HAVE_LIBPNG_PNG_H
5786 # include <libpng/png.h>
5787 #else
5788 # include <png.h>
5789 #endif
5791 #ifdef HAVE_NTGUI
5792 /* PNG library details. */
5794 DEF_IMGLIB_FN (png_get_io_ptr);
5795 DEF_IMGLIB_FN (png_check_sig);
5796 DEF_IMGLIB_FN (png_create_read_struct);
5797 DEF_IMGLIB_FN (png_create_info_struct);
5798 DEF_IMGLIB_FN (png_destroy_read_struct);
5799 DEF_IMGLIB_FN (png_set_read_fn);
5800 DEF_IMGLIB_FN (png_set_sig_bytes);
5801 DEF_IMGLIB_FN (png_read_info);
5802 DEF_IMGLIB_FN (png_get_IHDR);
5803 DEF_IMGLIB_FN (png_get_valid);
5804 DEF_IMGLIB_FN (png_set_strip_16);
5805 DEF_IMGLIB_FN (png_set_expand);
5806 DEF_IMGLIB_FN (png_set_gray_to_rgb);
5807 DEF_IMGLIB_FN (png_set_background);
5808 DEF_IMGLIB_FN (png_get_bKGD);
5809 DEF_IMGLIB_FN (png_read_update_info);
5810 DEF_IMGLIB_FN (png_get_channels);
5811 DEF_IMGLIB_FN (png_get_rowbytes);
5812 DEF_IMGLIB_FN (png_read_image);
5813 DEF_IMGLIB_FN (png_read_end);
5814 DEF_IMGLIB_FN (png_error);
5816 static int
5817 init_png_functions (Lisp_Object libraries)
5819 HMODULE library;
5821 /* Try loading libpng under probable names. */
5822 if (!(library = w32_delayed_load (libraries, Qpng)))
5823 return 0;
5825 LOAD_IMGLIB_FN (library, png_get_io_ptr);
5826 LOAD_IMGLIB_FN (library, png_check_sig);
5827 LOAD_IMGLIB_FN (library, png_create_read_struct);
5828 LOAD_IMGLIB_FN (library, png_create_info_struct);
5829 LOAD_IMGLIB_FN (library, png_destroy_read_struct);
5830 LOAD_IMGLIB_FN (library, png_set_read_fn);
5831 LOAD_IMGLIB_FN (library, png_set_sig_bytes);
5832 LOAD_IMGLIB_FN (library, png_read_info);
5833 LOAD_IMGLIB_FN (library, png_get_IHDR);
5834 LOAD_IMGLIB_FN (library, png_get_valid);
5835 LOAD_IMGLIB_FN (library, png_set_strip_16);
5836 LOAD_IMGLIB_FN (library, png_set_expand);
5837 LOAD_IMGLIB_FN (library, png_set_gray_to_rgb);
5838 LOAD_IMGLIB_FN (library, png_set_background);
5839 LOAD_IMGLIB_FN (library, png_get_bKGD);
5840 LOAD_IMGLIB_FN (library, png_read_update_info);
5841 LOAD_IMGLIB_FN (library, png_get_channels);
5842 LOAD_IMGLIB_FN (library, png_get_rowbytes);
5843 LOAD_IMGLIB_FN (library, png_read_image);
5844 LOAD_IMGLIB_FN (library, png_read_end);
5845 LOAD_IMGLIB_FN (library, png_error);
5846 return 1;
5848 #else
5850 #define fn_png_get_io_ptr png_get_io_ptr
5851 #define fn_png_check_sig png_check_sig
5852 #define fn_png_create_read_struct png_create_read_struct
5853 #define fn_png_create_info_struct png_create_info_struct
5854 #define fn_png_destroy_read_struct png_destroy_read_struct
5855 #define fn_png_set_read_fn png_set_read_fn
5856 #define fn_png_set_sig_bytes png_set_sig_bytes
5857 #define fn_png_read_info png_read_info
5858 #define fn_png_get_IHDR png_get_IHDR
5859 #define fn_png_get_valid png_get_valid
5860 #define fn_png_set_strip_16 png_set_strip_16
5861 #define fn_png_set_expand png_set_expand
5862 #define fn_png_set_gray_to_rgb png_set_gray_to_rgb
5863 #define fn_png_set_background png_set_background
5864 #define fn_png_get_bKGD png_get_bKGD
5865 #define fn_png_read_update_info png_read_update_info
5866 #define fn_png_get_channels png_get_channels
5867 #define fn_png_get_rowbytes png_get_rowbytes
5868 #define fn_png_read_image png_read_image
5869 #define fn_png_read_end png_read_end
5870 #define fn_png_error png_error
5872 #endif /* HAVE_NTGUI */
5874 /* Error and warning handlers installed when the PNG library
5875 is initialized. */
5877 static void
5878 my_png_error (png_ptr, msg)
5879 png_struct *png_ptr;
5880 char *msg;
5882 xassert (png_ptr != NULL);
5883 image_error ("PNG error: %s", build_string (msg), Qnil);
5884 longjmp (png_ptr->jmpbuf, 1);
5888 static void
5889 my_png_warning (png_ptr, msg)
5890 png_struct *png_ptr;
5891 char *msg;
5893 xassert (png_ptr != NULL);
5894 image_error ("PNG warning: %s", build_string (msg), Qnil);
5897 /* Memory source for PNG decoding. */
5899 struct png_memory_storage
5901 unsigned char *bytes; /* The data */
5902 size_t len; /* How big is it? */
5903 int index; /* Where are we? */
5907 /* Function set as reader function when reading PNG image from memory.
5908 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5909 bytes from the input to DATA. */
5911 static void
5912 png_read_from_memory (png_ptr, data, length)
5913 png_structp png_ptr;
5914 png_bytep data;
5915 png_size_t length;
5917 struct png_memory_storage *tbr
5918 = (struct png_memory_storage *) fn_png_get_io_ptr (png_ptr);
5920 if (length > tbr->len - tbr->index)
5921 fn_png_error (png_ptr, "Read error");
5923 bcopy (tbr->bytes + tbr->index, data, length);
5924 tbr->index = tbr->index + length;
5928 /* Function set as reader function when reading PNG image from a file.
5929 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5930 bytes from the input to DATA. */
5932 static void
5933 png_read_from_file (png_ptr, data, length)
5934 png_structp png_ptr;
5935 png_bytep data;
5936 png_size_t length;
5938 FILE *fp = (FILE *) fn_png_get_io_ptr (png_ptr);
5940 if (fread (data, 1, length, fp) < length)
5941 fn_png_error (png_ptr, "Read error");
5945 /* Load PNG image IMG for use on frame F. Value is non-zero if
5946 successful. */
5948 static int
5949 png_load (f, img)
5950 struct frame *f;
5951 struct image *img;
5953 Lisp_Object file, specified_file;
5954 Lisp_Object specified_data;
5955 int x, y, i;
5956 XImagePtr ximg, mask_img = NULL;
5957 struct gcpro gcpro1;
5958 png_struct *png_ptr = NULL;
5959 png_info *info_ptr = NULL, *end_info = NULL;
5960 FILE *volatile fp = NULL;
5961 png_byte sig[8];
5962 png_byte * volatile pixels = NULL;
5963 png_byte ** volatile rows = NULL;
5964 png_uint_32 width, height;
5965 int bit_depth, color_type, interlace_type;
5966 png_byte channels;
5967 png_uint_32 row_bytes;
5968 int transparent_p;
5969 struct png_memory_storage tbr; /* Data to be read */
5971 /* Find out what file to load. */
5972 specified_file = image_spec_value (img->spec, QCfile, NULL);
5973 specified_data = image_spec_value (img->spec, QCdata, NULL);
5974 file = Qnil;
5975 GCPRO1 (file);
5977 if (NILP (specified_data))
5979 file = x_find_image_file (specified_file);
5980 if (!STRINGP (file))
5982 image_error ("Cannot find image file `%s'", specified_file, Qnil);
5983 UNGCPRO;
5984 return 0;
5987 /* Open the image file. */
5988 fp = fopen (SDATA (file), "rb");
5989 if (!fp)
5991 image_error ("Cannot open image file `%s'", file, Qnil);
5992 UNGCPRO;
5993 return 0;
5996 /* Check PNG signature. */
5997 if (fread (sig, 1, sizeof sig, fp) != sizeof sig
5998 || !fn_png_check_sig (sig, sizeof sig))
6000 image_error ("Not a PNG file: `%s'", file, Qnil);
6001 UNGCPRO;
6002 fclose (fp);
6003 return 0;
6006 else
6008 /* Read from memory. */
6009 tbr.bytes = SDATA (specified_data);
6010 tbr.len = SBYTES (specified_data);
6011 tbr.index = 0;
6013 /* Check PNG signature. */
6014 if (tbr.len < sizeof sig
6015 || !fn_png_check_sig (tbr.bytes, sizeof sig))
6017 image_error ("Not a PNG image: `%s'", img->spec, Qnil);
6018 UNGCPRO;
6019 return 0;
6022 /* Need to skip past the signature. */
6023 tbr.bytes += sizeof (sig);
6026 /* Initialize read and info structs for PNG lib. Casting return
6027 value avoids a GCC warning on W32. */
6028 png_ptr = (png_structp)fn_png_create_read_struct (PNG_LIBPNG_VER_STRING,
6029 NULL, my_png_error,
6030 my_png_warning);
6031 if (!png_ptr)
6033 if (fp) fclose (fp);
6034 UNGCPRO;
6035 return 0;
6038 /* Casting return value avoids a GCC warning on W32. */
6039 info_ptr = (png_infop)fn_png_create_info_struct (png_ptr);
6040 if (!info_ptr)
6042 fn_png_destroy_read_struct (&png_ptr, NULL, NULL);
6043 if (fp) fclose (fp);
6044 UNGCPRO;
6045 return 0;
6048 /* Casting return value avoids a GCC warning on W32. */
6049 end_info = (png_infop)fn_png_create_info_struct (png_ptr);
6050 if (!end_info)
6052 fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
6053 if (fp) fclose (fp);
6054 UNGCPRO;
6055 return 0;
6058 /* Set error jump-back. We come back here when the PNG library
6059 detects an error. */
6060 if (setjmp (png_ptr->jmpbuf))
6062 error:
6063 if (png_ptr)
6064 fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
6065 xfree (pixels);
6066 xfree (rows);
6067 if (fp) fclose (fp);
6068 UNGCPRO;
6069 return 0;
6072 /* Read image info. */
6073 if (!NILP (specified_data))
6074 fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory);
6075 else
6076 fn_png_set_read_fn (png_ptr, (void *) fp, png_read_from_file);
6078 fn_png_set_sig_bytes (png_ptr, sizeof sig);
6079 fn_png_read_info (png_ptr, info_ptr);
6080 fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
6081 &interlace_type, NULL, NULL);
6083 if (!check_image_size (f, width, height))
6084 goto error;
6086 /* If image contains simply transparency data, we prefer to
6087 construct a clipping mask. */
6088 if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
6089 transparent_p = 1;
6090 else
6091 transparent_p = 0;
6093 /* This function is easier to write if we only have to handle
6094 one data format: RGB or RGBA with 8 bits per channel. Let's
6095 transform other formats into that format. */
6097 /* Strip more than 8 bits per channel. */
6098 if (bit_depth == 16)
6099 fn_png_set_strip_16 (png_ptr);
6101 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
6102 if available. */
6103 fn_png_set_expand (png_ptr);
6105 /* Convert grayscale images to RGB. */
6106 if (color_type == PNG_COLOR_TYPE_GRAY
6107 || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
6108 fn_png_set_gray_to_rgb (png_ptr);
6110 /* Handle alpha channel by combining the image with a background
6111 color. Do this only if a real alpha channel is supplied. For
6112 simple transparency, we prefer a clipping mask. */
6113 if (!transparent_p)
6115 /* png_color_16 *image_bg; */
6116 Lisp_Object specified_bg
6117 = image_spec_value (img->spec, QCbackground, NULL);
6118 int shift = (bit_depth == 16) ? 0 : 8;
6120 if (STRINGP (specified_bg))
6121 /* The user specified `:background', use that. */
6123 /* W32 version incorrectly used COLORREF here!! ++kfs */
6124 XColor color;
6125 if (x_defined_color (f, SDATA (specified_bg), &color, 0))
6127 png_color_16 user_bg;
6129 bzero (&user_bg, sizeof user_bg);
6130 user_bg.red = color.red >> shift;
6131 user_bg.green = color.green >> shift;
6132 user_bg.blue = color.blue >> shift;
6134 fn_png_set_background (png_ptr, &user_bg,
6135 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
6138 else
6140 /* We use the current frame background, ignoring any default
6141 background color set by the image. */
6142 #ifdef HAVE_X_WINDOWS
6143 XColor color;
6144 png_color_16 frame_background;
6146 color.pixel = FRAME_BACKGROUND_PIXEL (f);
6147 x_query_color (f, &color);
6149 bzero (&frame_background, sizeof frame_background);
6150 frame_background.red = color.red >> shift;
6151 frame_background.green = color.green >> shift;
6152 frame_background.blue = color.blue >> shift;
6153 #endif /* HAVE_X_WINDOWS */
6155 #ifdef HAVE_NTGUI
6156 COLORREF color;
6157 png_color_16 frame_background;
6158 color = FRAME_BACKGROUND_PIXEL (f);
6159 #if 0 /* W32 TODO : Colormap support. */
6160 x_query_color (f, &color);
6161 #endif
6162 bzero (&frame_background, sizeof frame_background);
6163 frame_background.red = GetRValue (color);
6164 frame_background.green = GetGValue (color);
6165 frame_background.blue = GetBValue (color);
6166 #endif /* HAVE_NTGUI */
6168 fn_png_set_background (png_ptr, &frame_background,
6169 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
6173 /* Update info structure. */
6174 fn_png_read_update_info (png_ptr, info_ptr);
6176 /* Get number of channels. Valid values are 1 for grayscale images
6177 and images with a palette, 2 for grayscale images with transparency
6178 information (alpha channel), 3 for RGB images, and 4 for RGB
6179 images with alpha channel, i.e. RGBA. If conversions above were
6180 sufficient we should only have 3 or 4 channels here. */
6181 channels = fn_png_get_channels (png_ptr, info_ptr);
6182 xassert (channels == 3 || channels == 4);
6184 /* Number of bytes needed for one row of the image. */
6185 row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr);
6187 /* Allocate memory for the image. */
6188 pixels = (png_byte *) xmalloc (row_bytes * height * sizeof *pixels);
6189 rows = (png_byte **) xmalloc (height * sizeof *rows);
6190 for (i = 0; i < height; ++i)
6191 rows[i] = pixels + i * row_bytes;
6193 /* Read the entire image. */
6194 fn_png_read_image (png_ptr, rows);
6195 fn_png_read_end (png_ptr, info_ptr);
6196 if (fp)
6198 fclose (fp);
6199 fp = NULL;
6202 /* Create the X image and pixmap. */
6203 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,
6204 &img->pixmap))
6205 goto error;
6207 /* Create an image and pixmap serving as mask if the PNG image
6208 contains an alpha channel. */
6209 if (channels == 4
6210 && !transparent_p
6211 && !x_create_x_image_and_pixmap (f, width, height, 1,
6212 &mask_img, &img->mask))
6214 x_destroy_x_image (ximg);
6215 Free_Pixmap (FRAME_X_DISPLAY (f), img->pixmap);
6216 img->pixmap = NO_PIXMAP;
6217 goto error;
6220 /* Fill the X image and mask from PNG data. */
6221 init_color_table ();
6223 for (y = 0; y < height; ++y)
6225 png_byte *p = rows[y];
6227 for (x = 0; x < width; ++x)
6229 unsigned r, g, b;
6231 r = *p++ << 8;
6232 g = *p++ << 8;
6233 b = *p++ << 8;
6234 XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
6235 /* An alpha channel, aka mask channel, associates variable
6236 transparency with an image. Where other image formats
6237 support binary transparency---fully transparent or fully
6238 opaque---PNG allows up to 254 levels of partial transparency.
6239 The PNG library implements partial transparency by combining
6240 the image with a specified background color.
6242 I'm not sure how to handle this here nicely: because the
6243 background on which the image is displayed may change, for
6244 real alpha channel support, it would be necessary to create
6245 a new image for each possible background.
6247 What I'm doing now is that a mask is created if we have
6248 boolean transparency information. Otherwise I'm using
6249 the frame's background color to combine the image with. */
6251 if (channels == 4)
6253 if (mask_img)
6254 XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN);
6255 ++p;
6260 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
6261 /* Set IMG's background color from the PNG image, unless the user
6262 overrode it. */
6264 png_color_16 *bg;
6265 if (fn_png_get_bKGD (png_ptr, info_ptr, &bg))
6267 img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue);
6268 img->background_valid = 1;
6272 #ifdef COLOR_TABLE_SUPPORT
6273 /* Remember colors allocated for this image. */
6274 img->colors = colors_in_color_table (&img->ncolors);
6275 free_color_table ();
6276 #endif /* COLOR_TABLE_SUPPORT */
6278 /* Clean up. */
6279 fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
6280 xfree (rows);
6281 xfree (pixels);
6283 img->width = width;
6284 img->height = height;
6286 /* Maybe fill in the background field while we have ximg handy.
6287 Casting avoids a GCC warning. */
6288 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
6290 /* Put the image into the pixmap, then free the X image and its buffer. */
6291 x_put_x_image (f, ximg, img->pixmap, width, height);
6292 x_destroy_x_image (ximg);
6294 /* Same for the mask. */
6295 if (mask_img)
6297 /* Fill in the background_transparent field while we have the
6298 mask handy. Casting avoids a GCC warning. */
6299 image_background_transparent (img, f, (XImagePtr_or_DC)mask_img);
6301 x_put_x_image (f, mask_img, img->mask, img->width, img->height);
6302 x_destroy_x_image (mask_img);
6305 UNGCPRO;
6306 return 1;
6309 #else /* HAVE_PNG */
6311 #ifdef HAVE_NS
6312 static int
6313 png_load (struct frame *f, struct image *img)
6315 return ns_load_image(f, img,
6316 image_spec_value (img->spec, QCfile, NULL),
6317 image_spec_value (img->spec, QCdata, NULL));
6319 #endif /* HAVE_NS */
6322 #endif /* !HAVE_PNG */
6326 /***********************************************************************
6327 JPEG
6328 ***********************************************************************/
6330 #if defined (HAVE_JPEG) || defined (HAVE_NS)
6332 static int jpeg_image_p P_ ((Lisp_Object object));
6333 static int jpeg_load P_ ((struct frame *f, struct image *img));
6335 /* The symbol `jpeg' identifying images of this type. */
6337 Lisp_Object Qjpeg;
6339 /* Indices of image specification fields in gs_format, below. */
6341 enum jpeg_keyword_index
6343 JPEG_TYPE,
6344 JPEG_DATA,
6345 JPEG_FILE,
6346 JPEG_ASCENT,
6347 JPEG_MARGIN,
6348 JPEG_RELIEF,
6349 JPEG_ALGORITHM,
6350 JPEG_HEURISTIC_MASK,
6351 JPEG_MASK,
6352 JPEG_BACKGROUND,
6353 JPEG_LAST
6356 /* Vector of image_keyword structures describing the format
6357 of valid user-defined image specifications. */
6359 static struct image_keyword jpeg_format[JPEG_LAST] =
6361 {":type", IMAGE_SYMBOL_VALUE, 1},
6362 {":data", IMAGE_STRING_VALUE, 0},
6363 {":file", IMAGE_STRING_VALUE, 0},
6364 {":ascent", IMAGE_ASCENT_VALUE, 0},
6365 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
6366 {":relief", IMAGE_INTEGER_VALUE, 0},
6367 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6368 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6369 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6370 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
6373 /* Structure describing the image type `jpeg'. */
6375 static struct image_type jpeg_type =
6377 &Qjpeg,
6378 jpeg_image_p,
6379 jpeg_load,
6380 x_clear_image,
6381 NULL
6384 /* Return non-zero if OBJECT is a valid JPEG image specification. */
6386 static int
6387 jpeg_image_p (object)
6388 Lisp_Object object;
6390 struct image_keyword fmt[JPEG_LAST];
6392 bcopy (jpeg_format, fmt, sizeof fmt);
6394 if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg))
6395 return 0;
6397 /* Must specify either the :data or :file keyword. */
6398 return fmt[JPEG_FILE].count + fmt[JPEG_DATA].count == 1;
6401 #endif /* HAVE_JPEG || HAVE_NS */
6403 #ifdef HAVE_JPEG
6405 /* Work around a warning about HAVE_STDLIB_H being redefined in
6406 jconfig.h. */
6407 #ifdef HAVE_STDLIB_H
6408 #define HAVE_STDLIB_H_1
6409 #undef HAVE_STDLIB_H
6410 #endif /* HAVE_STLIB_H */
6412 #if defined (HAVE_NTGUI) && !defined (__WIN32__)
6413 /* In older releases of the jpeg library, jpeglib.h will define boolean
6414 differently depending on __WIN32__, so make sure it is defined. */
6415 #define __WIN32__ 1
6416 #endif
6418 #include <jpeglib.h>
6419 #include <jerror.h>
6420 #include <setjmp.h>
6422 #ifdef HAVE_STLIB_H_1
6423 #define HAVE_STDLIB_H 1
6424 #endif
6426 #ifdef HAVE_NTGUI
6428 /* JPEG library details. */
6429 DEF_IMGLIB_FN (jpeg_CreateDecompress);
6430 DEF_IMGLIB_FN (jpeg_start_decompress);
6431 DEF_IMGLIB_FN (jpeg_finish_decompress);
6432 DEF_IMGLIB_FN (jpeg_destroy_decompress);
6433 DEF_IMGLIB_FN (jpeg_read_header);
6434 DEF_IMGLIB_FN (jpeg_read_scanlines);
6435 DEF_IMGLIB_FN (jpeg_std_error);
6436 DEF_IMGLIB_FN (jpeg_resync_to_restart);
6438 static int
6439 init_jpeg_functions (Lisp_Object libraries)
6441 HMODULE library;
6443 if (!(library = w32_delayed_load (libraries, Qjpeg)))
6444 return 0;
6446 LOAD_IMGLIB_FN (library, jpeg_finish_decompress);
6447 LOAD_IMGLIB_FN (library, jpeg_read_scanlines);
6448 LOAD_IMGLIB_FN (library, jpeg_start_decompress);
6449 LOAD_IMGLIB_FN (library, jpeg_read_header);
6450 LOAD_IMGLIB_FN (library, jpeg_CreateDecompress);
6451 LOAD_IMGLIB_FN (library, jpeg_destroy_decompress);
6452 LOAD_IMGLIB_FN (library, jpeg_std_error);
6453 LOAD_IMGLIB_FN (library, jpeg_resync_to_restart);
6454 return 1;
6457 /* Wrapper since we can't directly assign the function pointer
6458 to another function pointer that was declared more completely easily. */
6459 static boolean
6460 jpeg_resync_to_restart_wrapper (cinfo, desired)
6461 j_decompress_ptr cinfo;
6462 int desired;
6464 return fn_jpeg_resync_to_restart (cinfo, desired);
6467 #else
6469 #define fn_jpeg_CreateDecompress(a,b,c) jpeg_create_decompress(a)
6470 #define fn_jpeg_start_decompress jpeg_start_decompress
6471 #define fn_jpeg_finish_decompress jpeg_finish_decompress
6472 #define fn_jpeg_destroy_decompress jpeg_destroy_decompress
6473 #define fn_jpeg_read_header jpeg_read_header
6474 #define fn_jpeg_read_scanlines jpeg_read_scanlines
6475 #define fn_jpeg_std_error jpeg_std_error
6476 #define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart
6478 #endif /* HAVE_NTGUI */
6480 struct my_jpeg_error_mgr
6482 struct jpeg_error_mgr pub;
6483 jmp_buf setjmp_buffer;
6487 static void
6488 my_error_exit (cinfo)
6489 j_common_ptr cinfo;
6491 struct my_jpeg_error_mgr *mgr = (struct my_jpeg_error_mgr *) cinfo->err;
6492 longjmp (mgr->setjmp_buffer, 1);
6496 /* Init source method for JPEG data source manager. Called by
6497 jpeg_read_header() before any data is actually read. See
6498 libjpeg.doc from the JPEG lib distribution. */
6500 static void
6501 our_common_init_source (cinfo)
6502 j_decompress_ptr cinfo;
6507 /* Method to terminate data source. Called by
6508 jpeg_finish_decompress() after all data has been processed. */
6510 static void
6511 our_common_term_source (cinfo)
6512 j_decompress_ptr cinfo;
6517 /* Fill input buffer method for JPEG data source manager. Called
6518 whenever more data is needed. We read the whole image in one step,
6519 so this only adds a fake end of input marker at the end. */
6521 static JOCTET our_memory_buffer[2];
6523 static boolean
6524 our_memory_fill_input_buffer (cinfo)
6525 j_decompress_ptr cinfo;
6527 /* Insert a fake EOI marker. */
6528 struct jpeg_source_mgr *src = cinfo->src;
6530 our_memory_buffer[0] = (JOCTET) 0xFF;
6531 our_memory_buffer[1] = (JOCTET) JPEG_EOI;
6533 src->next_input_byte = our_memory_buffer;
6534 src->bytes_in_buffer = 2;
6535 return 1;
6539 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6540 is the JPEG data source manager. */
6542 static void
6543 our_memory_skip_input_data (cinfo, num_bytes)
6544 j_decompress_ptr cinfo;
6545 long num_bytes;
6547 struct jpeg_source_mgr *src = (struct jpeg_source_mgr *) cinfo->src;
6549 if (src)
6551 if (num_bytes > src->bytes_in_buffer)
6552 ERREXIT (cinfo, JERR_INPUT_EOF);
6554 src->bytes_in_buffer -= num_bytes;
6555 src->next_input_byte += num_bytes;
6560 /* Set up the JPEG lib for reading an image from DATA which contains
6561 LEN bytes. CINFO is the decompression info structure created for
6562 reading the image. */
6564 static void
6565 jpeg_memory_src (cinfo, data, len)
6566 j_decompress_ptr cinfo;
6567 JOCTET *data;
6568 unsigned int len;
6570 struct jpeg_source_mgr *src;
6572 if (cinfo->src == NULL)
6574 /* First time for this JPEG object? */
6575 cinfo->src = (struct jpeg_source_mgr *)
6576 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
6577 sizeof (struct jpeg_source_mgr));
6578 src = (struct jpeg_source_mgr *) cinfo->src;
6579 src->next_input_byte = data;
6582 src = (struct jpeg_source_mgr *) cinfo->src;
6583 src->init_source = our_common_init_source;
6584 src->fill_input_buffer = our_memory_fill_input_buffer;
6585 src->skip_input_data = our_memory_skip_input_data;
6586 src->resync_to_restart = jpeg_resync_to_restart_wrapper; /* Use default method. */
6587 src->term_source = our_common_term_source;
6588 src->bytes_in_buffer = len;
6589 src->next_input_byte = data;
6593 struct jpeg_stdio_mgr
6595 struct jpeg_source_mgr mgr;
6596 boolean finished;
6597 FILE *file;
6598 JOCTET *buffer;
6602 /* Size of buffer to read JPEG from file.
6603 Not too big, as we want to use alloc_small. */
6604 #define JPEG_STDIO_BUFFER_SIZE 8192
6607 /* Fill input buffer method for JPEG data source manager. Called
6608 whenever more data is needed. The data is read from a FILE *. */
6610 static boolean
6611 our_stdio_fill_input_buffer (cinfo)
6612 j_decompress_ptr cinfo;
6614 struct jpeg_stdio_mgr *src;
6616 src = (struct jpeg_stdio_mgr *) cinfo->src;
6617 if (!src->finished)
6619 size_t bytes;
6621 bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file);
6622 if (bytes > 0)
6623 src->mgr.bytes_in_buffer = bytes;
6624 else
6626 WARNMS (cinfo, JWRN_JPEG_EOF);
6627 src->finished = 1;
6628 src->buffer[0] = (JOCTET) 0xFF;
6629 src->buffer[1] = (JOCTET) JPEG_EOI;
6630 src->mgr.bytes_in_buffer = 2;
6632 src->mgr.next_input_byte = src->buffer;
6635 return 1;
6639 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6640 is the JPEG data source manager. */
6642 static void
6643 our_stdio_skip_input_data (cinfo, num_bytes)
6644 j_decompress_ptr cinfo;
6645 long num_bytes;
6647 struct jpeg_stdio_mgr *src;
6648 src = (struct jpeg_stdio_mgr *) cinfo->src;
6650 while (num_bytes > 0 && !src->finished)
6652 if (num_bytes <= src->mgr.bytes_in_buffer)
6654 src->mgr.bytes_in_buffer -= num_bytes;
6655 src->mgr.next_input_byte += num_bytes;
6656 break;
6658 else
6660 num_bytes -= src->mgr.bytes_in_buffer;
6661 src->mgr.bytes_in_buffer = 0;
6662 src->mgr.next_input_byte = NULL;
6664 our_stdio_fill_input_buffer (cinfo);
6670 /* Set up the JPEG lib for reading an image from a FILE *.
6671 CINFO is the decompression info structure created for
6672 reading the image. */
6674 static void
6675 jpeg_file_src (cinfo, fp)
6676 j_decompress_ptr cinfo;
6677 FILE *fp;
6679 struct jpeg_stdio_mgr *src;
6681 if (cinfo->src != NULL)
6682 src = (struct jpeg_stdio_mgr *) cinfo->src;
6683 else
6685 /* First time for this JPEG object? */
6686 cinfo->src = (struct jpeg_source_mgr *)
6687 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
6688 sizeof (struct jpeg_stdio_mgr));
6689 src = (struct jpeg_stdio_mgr *) cinfo->src;
6690 src->buffer = (JOCTET *)
6691 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
6692 JPEG_STDIO_BUFFER_SIZE);
6695 src->file = fp;
6696 src->finished = 0;
6697 src->mgr.init_source = our_common_init_source;
6698 src->mgr.fill_input_buffer = our_stdio_fill_input_buffer;
6699 src->mgr.skip_input_data = our_stdio_skip_input_data;
6700 src->mgr.resync_to_restart = jpeg_resync_to_restart_wrapper; /* Use default method. */
6701 src->mgr.term_source = our_common_term_source;
6702 src->mgr.bytes_in_buffer = 0;
6703 src->mgr.next_input_byte = NULL;
6707 /* Load image IMG for use on frame F. Patterned after example.c
6708 from the JPEG lib. */
6710 static int
6711 jpeg_load (f, img)
6712 struct frame *f;
6713 struct image *img;
6715 struct jpeg_decompress_struct cinfo;
6716 struct my_jpeg_error_mgr mgr;
6717 Lisp_Object file, specified_file;
6718 Lisp_Object specified_data;
6719 FILE * volatile fp = NULL;
6720 JSAMPARRAY buffer;
6721 int row_stride, x, y;
6722 XImagePtr ximg = NULL;
6723 int rc;
6724 unsigned long *colors;
6725 int width, height;
6726 struct gcpro gcpro1;
6728 /* Open the JPEG file. */
6729 specified_file = image_spec_value (img->spec, QCfile, NULL);
6730 specified_data = image_spec_value (img->spec, QCdata, NULL);
6731 file = Qnil;
6732 GCPRO1 (file);
6734 if (NILP (specified_data))
6736 file = x_find_image_file (specified_file);
6737 if (!STRINGP (file))
6739 image_error ("Cannot find image file `%s'", specified_file, Qnil);
6740 UNGCPRO;
6741 return 0;
6744 fp = fopen (SDATA (file), "rb");
6745 if (fp == NULL)
6747 image_error ("Cannot open `%s'", file, Qnil);
6748 UNGCPRO;
6749 return 0;
6753 /* Customize libjpeg's error handling to call my_error_exit when an
6754 error is detected. This function will perform a longjmp.
6755 Casting return value avoids a GCC warning on W32. */
6756 cinfo.err = (struct jpeg_error_mgr *)fn_jpeg_std_error (&mgr.pub);
6757 mgr.pub.error_exit = my_error_exit;
6759 if ((rc = setjmp (mgr.setjmp_buffer)) != 0)
6761 if (rc == 1)
6763 /* Called from my_error_exit. Display a JPEG error. */
6764 char buffer[JMSG_LENGTH_MAX];
6765 cinfo.err->format_message ((j_common_ptr) &cinfo, buffer);
6766 image_error ("Error reading JPEG image `%s': %s", img->spec,
6767 build_string (buffer));
6770 /* Close the input file and destroy the JPEG object. */
6771 if (fp)
6772 fclose ((FILE *) fp);
6773 fn_jpeg_destroy_decompress (&cinfo);
6775 /* If we already have an XImage, free that. */
6776 x_destroy_x_image (ximg);
6778 /* Free pixmap and colors. */
6779 x_clear_image (f, img);
6781 UNGCPRO;
6782 return 0;
6785 /* Create the JPEG decompression object. Let it read from fp.
6786 Read the JPEG image header. */
6787 fn_jpeg_CreateDecompress (&cinfo, JPEG_LIB_VERSION, sizeof (cinfo));
6789 if (NILP (specified_data))
6790 jpeg_file_src (&cinfo, (FILE *) fp);
6791 else
6792 jpeg_memory_src (&cinfo, SDATA (specified_data),
6793 SBYTES (specified_data));
6795 fn_jpeg_read_header (&cinfo, 1);
6797 /* Customize decompression so that color quantization will be used.
6798 Start decompression. */
6799 cinfo.quantize_colors = 1;
6800 fn_jpeg_start_decompress (&cinfo);
6801 width = img->width = cinfo.output_width;
6802 height = img->height = cinfo.output_height;
6804 if (!check_image_size (f, width, height))
6806 image_error ("Invalid image size", Qnil, Qnil);
6807 longjmp (mgr.setjmp_buffer, 2);
6810 /* Create X image and pixmap. */
6811 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
6812 longjmp (mgr.setjmp_buffer, 2);
6814 /* Allocate colors. When color quantization is used,
6815 cinfo.actual_number_of_colors has been set with the number of
6816 colors generated, and cinfo.colormap is a two-dimensional array
6817 of color indices in the range 0..cinfo.actual_number_of_colors.
6818 No more than 255 colors will be generated. */
6820 int i, ir, ig, ib;
6822 if (cinfo.out_color_components > 2)
6823 ir = 0, ig = 1, ib = 2;
6824 else if (cinfo.out_color_components > 1)
6825 ir = 0, ig = 1, ib = 0;
6826 else
6827 ir = 0, ig = 0, ib = 0;
6829 /* Use the color table mechanism because it handles colors that
6830 cannot be allocated nicely. Such colors will be replaced with
6831 a default color, and we don't have to care about which colors
6832 can be freed safely, and which can't. */
6833 init_color_table ();
6834 colors = (unsigned long *) alloca (cinfo.actual_number_of_colors
6835 * sizeof *colors);
6837 for (i = 0; i < cinfo.actual_number_of_colors; ++i)
6839 /* Multiply RGB values with 255 because X expects RGB values
6840 in the range 0..0xffff. */
6841 int r = cinfo.colormap[ir][i] << 8;
6842 int g = cinfo.colormap[ig][i] << 8;
6843 int b = cinfo.colormap[ib][i] << 8;
6844 colors[i] = lookup_rgb_color (f, r, g, b);
6847 #ifdef COLOR_TABLE_SUPPORT
6848 /* Remember those colors actually allocated. */
6849 img->colors = colors_in_color_table (&img->ncolors);
6850 free_color_table ();
6851 #endif /* COLOR_TABLE_SUPPORT */
6854 /* Read pixels. */
6855 row_stride = width * cinfo.output_components;
6856 buffer = cinfo.mem->alloc_sarray ((j_common_ptr) &cinfo, JPOOL_IMAGE,
6857 row_stride, 1);
6858 for (y = 0; y < height; ++y)
6860 fn_jpeg_read_scanlines (&cinfo, buffer, 1);
6861 for (x = 0; x < cinfo.output_width; ++x)
6862 XPutPixel (ximg, x, y, colors[buffer[0][x]]);
6865 /* Clean up. */
6866 fn_jpeg_finish_decompress (&cinfo);
6867 fn_jpeg_destroy_decompress (&cinfo);
6868 if (fp)
6869 fclose ((FILE *) fp);
6871 /* Maybe fill in the background field while we have ximg handy. */
6872 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
6873 /* Casting avoids a GCC warning. */
6874 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
6876 /* Put the image into the pixmap. */
6877 x_put_x_image (f, ximg, img->pixmap, width, height);
6878 x_destroy_x_image (ximg);
6879 UNGCPRO;
6880 return 1;
6883 #else /* HAVE_JPEG */
6885 #ifdef HAVE_NS
6886 static int
6887 jpeg_load (struct frame *f, struct image *img)
6889 return ns_load_image(f, img,
6890 image_spec_value (img->spec, QCfile, NULL),
6891 image_spec_value (img->spec, QCdata, NULL));
6893 #endif /* HAVE_NS */
6895 #endif /* !HAVE_JPEG */
6899 /***********************************************************************
6900 TIFF
6901 ***********************************************************************/
6903 #if defined (HAVE_TIFF) || defined (HAVE_NS)
6905 static int tiff_image_p P_ ((Lisp_Object object));
6906 static int tiff_load P_ ((struct frame *f, struct image *img));
6908 /* The symbol `tiff' identifying images of this type. */
6910 Lisp_Object Qtiff;
6912 /* Indices of image specification fields in tiff_format, below. */
6914 enum tiff_keyword_index
6916 TIFF_TYPE,
6917 TIFF_DATA,
6918 TIFF_FILE,
6919 TIFF_ASCENT,
6920 TIFF_MARGIN,
6921 TIFF_RELIEF,
6922 TIFF_ALGORITHM,
6923 TIFF_HEURISTIC_MASK,
6924 TIFF_MASK,
6925 TIFF_BACKGROUND,
6926 TIFF_INDEX,
6927 TIFF_LAST
6930 /* Vector of image_keyword structures describing the format
6931 of valid user-defined image specifications. */
6933 static struct image_keyword tiff_format[TIFF_LAST] =
6935 {":type", IMAGE_SYMBOL_VALUE, 1},
6936 {":data", IMAGE_STRING_VALUE, 0},
6937 {":file", IMAGE_STRING_VALUE, 0},
6938 {":ascent", IMAGE_ASCENT_VALUE, 0},
6939 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
6940 {":relief", IMAGE_INTEGER_VALUE, 0},
6941 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6942 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6943 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6944 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
6945 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}
6948 /* Structure describing the image type `tiff'. */
6950 static struct image_type tiff_type =
6952 &Qtiff,
6953 tiff_image_p,
6954 tiff_load,
6955 x_clear_image,
6956 NULL
6959 /* Return non-zero if OBJECT is a valid TIFF image specification. */
6961 static int
6962 tiff_image_p (object)
6963 Lisp_Object object;
6965 struct image_keyword fmt[TIFF_LAST];
6966 bcopy (tiff_format, fmt, sizeof fmt);
6968 if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff))
6969 return 0;
6971 /* Must specify either the :data or :file keyword. */
6972 return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1;
6975 #endif /* HAVE_TIFF || HAVE_NS */
6977 #ifdef HAVE_TIFF
6979 #include <tiffio.h>
6981 #ifdef HAVE_NTGUI
6983 /* TIFF library details. */
6984 DEF_IMGLIB_FN (TIFFSetErrorHandler);
6985 DEF_IMGLIB_FN (TIFFSetWarningHandler);
6986 DEF_IMGLIB_FN (TIFFOpen);
6987 DEF_IMGLIB_FN (TIFFClientOpen);
6988 DEF_IMGLIB_FN (TIFFGetField);
6989 DEF_IMGLIB_FN (TIFFReadRGBAImage);
6990 DEF_IMGLIB_FN (TIFFClose);
6991 DEF_IMGLIB_FN (TIFFSetDirectory);
6993 static int
6994 init_tiff_functions (Lisp_Object libraries)
6996 HMODULE library;
6998 if (!(library = w32_delayed_load (libraries, Qtiff)))
6999 return 0;
7001 LOAD_IMGLIB_FN (library, TIFFSetErrorHandler);
7002 LOAD_IMGLIB_FN (library, TIFFSetWarningHandler);
7003 LOAD_IMGLIB_FN (library, TIFFOpen);
7004 LOAD_IMGLIB_FN (library, TIFFClientOpen);
7005 LOAD_IMGLIB_FN (library, TIFFGetField);
7006 LOAD_IMGLIB_FN (library, TIFFReadRGBAImage);
7007 LOAD_IMGLIB_FN (library, TIFFClose);
7008 LOAD_IMGLIB_FN (library, TIFFSetDirectory);
7009 return 1;
7012 #else
7014 #define fn_TIFFSetErrorHandler TIFFSetErrorHandler
7015 #define fn_TIFFSetWarningHandler TIFFSetWarningHandler
7016 #define fn_TIFFOpen TIFFOpen
7017 #define fn_TIFFClientOpen TIFFClientOpen
7018 #define fn_TIFFGetField TIFFGetField
7019 #define fn_TIFFReadRGBAImage TIFFReadRGBAImage
7020 #define fn_TIFFClose TIFFClose
7021 #define fn_TIFFSetDirectory TIFFSetDirectory
7022 #endif /* HAVE_NTGUI */
7025 /* Reading from a memory buffer for TIFF images Based on the PNG
7026 memory source, but we have to provide a lot of extra functions.
7027 Blah.
7029 We really only need to implement read and seek, but I am not
7030 convinced that the TIFF library is smart enough not to destroy
7031 itself if we only hand it the function pointers we need to
7032 override. */
7034 typedef struct
7036 unsigned char *bytes;
7037 size_t len;
7038 int index;
7040 tiff_memory_source;
7042 static size_t
7043 tiff_read_from_memory (data, buf, size)
7044 thandle_t data;
7045 tdata_t buf;
7046 tsize_t size;
7048 tiff_memory_source *src = (tiff_memory_source *) data;
7050 if (size > src->len - src->index)
7051 return (size_t) -1;
7052 bcopy (src->bytes + src->index, buf, size);
7053 src->index += size;
7054 return size;
7057 static size_t
7058 tiff_write_from_memory (data, buf, size)
7059 thandle_t data;
7060 tdata_t buf;
7061 tsize_t size;
7063 return (size_t) -1;
7066 static toff_t
7067 tiff_seek_in_memory (data, off, whence)
7068 thandle_t data;
7069 toff_t off;
7070 int whence;
7072 tiff_memory_source *src = (tiff_memory_source *) data;
7073 int idx;
7075 switch (whence)
7077 case SEEK_SET: /* Go from beginning of source. */
7078 idx = off;
7079 break;
7081 case SEEK_END: /* Go from end of source. */
7082 idx = src->len + off;
7083 break;
7085 case SEEK_CUR: /* Go from current position. */
7086 idx = src->index + off;
7087 break;
7089 default: /* Invalid `whence'. */
7090 return -1;
7093 if (idx > src->len || idx < 0)
7094 return -1;
7096 src->index = idx;
7097 return src->index;
7100 static int
7101 tiff_close_memory (data)
7102 thandle_t data;
7104 /* NOOP */
7105 return 0;
7108 static int
7109 tiff_mmap_memory (data, pbase, psize)
7110 thandle_t data;
7111 tdata_t *pbase;
7112 toff_t *psize;
7114 /* It is already _IN_ memory. */
7115 return 0;
7118 static void
7119 tiff_unmap_memory (data, base, size)
7120 thandle_t data;
7121 tdata_t base;
7122 toff_t size;
7124 /* We don't need to do this. */
7127 static toff_t
7128 tiff_size_of_memory (data)
7129 thandle_t data;
7131 return ((tiff_memory_source *) data)->len;
7135 static void
7136 tiff_error_handler (title, format, ap)
7137 const char *title, *format;
7138 va_list ap;
7140 char buf[512];
7141 int len;
7143 len = sprintf (buf, "TIFF error: %s ", title);
7144 vsprintf (buf + len, format, ap);
7145 add_to_log (buf, Qnil, Qnil);
7149 static void
7150 tiff_warning_handler (title, format, ap)
7151 const char *title, *format;
7152 va_list ap;
7154 char buf[512];
7155 int len;
7157 len = sprintf (buf, "TIFF warning: %s ", title);
7158 vsprintf (buf + len, format, ap);
7159 add_to_log (buf, Qnil, Qnil);
7163 /* Load TIFF image IMG for use on frame F. Value is non-zero if
7164 successful. */
7166 static int
7167 tiff_load (f, img)
7168 struct frame *f;
7169 struct image *img;
7171 Lisp_Object file, specified_file;
7172 Lisp_Object specified_data;
7173 TIFF *tiff;
7174 int width, height, x, y, count;
7175 uint32 *buf;
7176 int rc, rc2;
7177 XImagePtr ximg;
7178 struct gcpro gcpro1;
7179 tiff_memory_source memsrc;
7180 Lisp_Object image;
7182 specified_file = image_spec_value (img->spec, QCfile, NULL);
7183 specified_data = image_spec_value (img->spec, QCdata, NULL);
7184 file = Qnil;
7185 GCPRO1 (file);
7187 fn_TIFFSetErrorHandler (tiff_error_handler);
7188 fn_TIFFSetWarningHandler (tiff_warning_handler);
7190 if (NILP (specified_data))
7192 /* Read from a file */
7193 file = x_find_image_file (specified_file);
7194 if (!STRINGP (file))
7196 image_error ("Cannot find image file `%s'", specified_file, Qnil);
7197 UNGCPRO;
7198 return 0;
7201 /* Try to open the image file. Casting return value avoids a
7202 GCC warning on W32. */
7203 tiff = (TIFF *)fn_TIFFOpen (SDATA (file), "r");
7204 if (tiff == NULL)
7206 image_error ("Cannot open `%s'", file, Qnil);
7207 UNGCPRO;
7208 return 0;
7211 else
7213 /* Memory source! */
7214 memsrc.bytes = SDATA (specified_data);
7215 memsrc.len = SBYTES (specified_data);
7216 memsrc.index = 0;
7218 /* Casting return value avoids a GCC warning on W32. */
7219 tiff = (TIFF *)fn_TIFFClientOpen ("memory_source", "r", &memsrc,
7220 (TIFFReadWriteProc) tiff_read_from_memory,
7221 (TIFFReadWriteProc) tiff_write_from_memory,
7222 tiff_seek_in_memory,
7223 tiff_close_memory,
7224 tiff_size_of_memory,
7225 tiff_mmap_memory,
7226 tiff_unmap_memory);
7228 if (!tiff)
7230 image_error ("Cannot open memory source for `%s'", img->spec, Qnil);
7231 UNGCPRO;
7232 return 0;
7236 image = image_spec_value (img->spec, QCindex, NULL);
7237 if (INTEGERP (image))
7239 int ino = XFASTINT (image);
7240 if (!fn_TIFFSetDirectory (tiff, ino))
7242 image_error ("Invalid image number `%s' in image `%s'",
7243 image, img->spec);
7244 fn_TIFFClose (tiff);
7245 UNGCPRO;
7246 return 0;
7250 /* Get width and height of the image, and allocate a raster buffer
7251 of width x height 32-bit values. */
7252 fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
7253 fn_TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
7255 if (!check_image_size (f, width, height))
7257 image_error ("Invalid image size", Qnil, Qnil);
7258 fn_TIFFClose (tiff);
7259 UNGCPRO;
7260 return 0;
7263 buf = (uint32 *) xmalloc (width * height * sizeof *buf);
7265 rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
7267 /* Count the number of images in the file. */
7268 for (count = 1, rc2 = 1; rc2; count++)
7269 rc2 = fn_TIFFSetDirectory (tiff, count);
7271 if (count > 1)
7272 img->data.lisp_val = Fcons (Qcount,
7273 Fcons (make_number (count),
7274 img->data.lisp_val));
7276 fn_TIFFClose (tiff);
7277 if (!rc)
7279 image_error ("Error reading TIFF image `%s'", img->spec, Qnil);
7280 xfree (buf);
7281 UNGCPRO;
7282 return 0;
7285 /* Create the X image and pixmap. */
7286 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
7288 xfree (buf);
7289 UNGCPRO;
7290 return 0;
7293 /* Initialize the color table. */
7294 init_color_table ();
7296 /* Process the pixel raster. Origin is in the lower-left corner. */
7297 for (y = 0; y < height; ++y)
7299 uint32 *row = buf + y * width;
7301 for (x = 0; x < width; ++x)
7303 uint32 abgr = row[x];
7304 int r = TIFFGetR (abgr) << 8;
7305 int g = TIFFGetG (abgr) << 8;
7306 int b = TIFFGetB (abgr) << 8;
7307 XPutPixel (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b));
7311 #ifdef COLOR_TABLE_SUPPORT
7312 /* Remember the colors allocated for the image. Free the color table. */
7313 img->colors = colors_in_color_table (&img->ncolors);
7314 free_color_table ();
7315 #endif /* COLOR_TABLE_SUPPORT */
7317 img->width = width;
7318 img->height = height;
7320 /* Maybe fill in the background field while we have ximg handy. */
7321 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7322 /* Casting avoids a GCC warning on W32. */
7323 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
7325 /* Put the image into the pixmap, then free the X image and its buffer. */
7326 x_put_x_image (f, ximg, img->pixmap, width, height);
7327 x_destroy_x_image (ximg);
7328 xfree (buf);
7330 UNGCPRO;
7331 return 1;
7334 #else /* HAVE_TIFF */
7336 #ifdef HAVE_NS
7337 static int
7338 tiff_load (struct frame *f, struct image *img)
7340 return ns_load_image(f, img,
7341 image_spec_value (img->spec, QCfile, NULL),
7342 image_spec_value (img->spec, QCdata, NULL));
7344 #endif /* HAVE_NS */
7346 #endif /* !HAVE_TIFF */
7350 /***********************************************************************
7352 ***********************************************************************/
7354 #if defined (HAVE_GIF) || defined (HAVE_NS)
7356 static int gif_image_p P_ ((Lisp_Object object));
7357 static int gif_load P_ ((struct frame *f, struct image *img));
7358 static void gif_clear_image P_ ((struct frame *f, struct image *img));
7360 /* The symbol `gif' identifying images of this type. */
7362 Lisp_Object Qgif;
7364 /* Indices of image specification fields in gif_format, below. */
7366 enum gif_keyword_index
7368 GIF_TYPE,
7369 GIF_DATA,
7370 GIF_FILE,
7371 GIF_ASCENT,
7372 GIF_MARGIN,
7373 GIF_RELIEF,
7374 GIF_ALGORITHM,
7375 GIF_HEURISTIC_MASK,
7376 GIF_MASK,
7377 GIF_IMAGE,
7378 GIF_BACKGROUND,
7379 GIF_LAST
7382 /* Vector of image_keyword structures describing the format
7383 of valid user-defined image specifications. */
7385 static struct image_keyword gif_format[GIF_LAST] =
7387 {":type", IMAGE_SYMBOL_VALUE, 1},
7388 {":data", IMAGE_STRING_VALUE, 0},
7389 {":file", IMAGE_STRING_VALUE, 0},
7390 {":ascent", IMAGE_ASCENT_VALUE, 0},
7391 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
7392 {":relief", IMAGE_INTEGER_VALUE, 0},
7393 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7394 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7395 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7396 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
7397 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
7400 /* Structure describing the image type `gif'. */
7402 static struct image_type gif_type =
7404 &Qgif,
7405 gif_image_p,
7406 gif_load,
7407 gif_clear_image,
7408 NULL
7411 /* Free X resources of GIF image IMG which is used on frame F. */
7413 static void
7414 gif_clear_image (f, img)
7415 struct frame *f;
7416 struct image *img;
7418 /* IMG->data.ptr_val may contain extension data. */
7419 img->data.lisp_val = Qnil;
7420 x_clear_image (f, img);
7423 /* Return non-zero if OBJECT is a valid GIF image specification. */
7425 static int
7426 gif_image_p (object)
7427 Lisp_Object object;
7429 struct image_keyword fmt[GIF_LAST];
7430 bcopy (gif_format, fmt, sizeof fmt);
7432 if (!parse_image_spec (object, fmt, GIF_LAST, Qgif))
7433 return 0;
7435 /* Must specify either the :data or :file keyword. */
7436 return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1;
7439 #endif /* HAVE_GIF */
7441 #ifdef HAVE_GIF
7443 #if defined (HAVE_NTGUI)
7444 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
7445 Undefine before redefining to avoid a preprocessor warning. */
7446 #ifdef DrawText
7447 #undef DrawText
7448 #endif
7449 /* avoid conflict with QuickdrawText.h */
7450 #define DrawText gif_DrawText
7451 #include <gif_lib.h>
7452 #undef DrawText
7454 #else /* HAVE_NTGUI */
7456 #include <gif_lib.h>
7458 #endif /* HAVE_NTGUI */
7461 #ifdef HAVE_NTGUI
7463 /* GIF library details. */
7464 DEF_IMGLIB_FN (DGifCloseFile);
7465 DEF_IMGLIB_FN (DGifSlurp);
7466 DEF_IMGLIB_FN (DGifOpen);
7467 DEF_IMGLIB_FN (DGifOpenFileName);
7469 static int
7470 init_gif_functions (Lisp_Object libraries)
7472 HMODULE library;
7474 if (!(library = w32_delayed_load (libraries, Qgif)))
7475 return 0;
7477 LOAD_IMGLIB_FN (library, DGifCloseFile);
7478 LOAD_IMGLIB_FN (library, DGifSlurp);
7479 LOAD_IMGLIB_FN (library, DGifOpen);
7480 LOAD_IMGLIB_FN (library, DGifOpenFileName);
7481 return 1;
7484 #else
7486 #define fn_DGifCloseFile DGifCloseFile
7487 #define fn_DGifSlurp DGifSlurp
7488 #define fn_DGifOpen DGifOpen
7489 #define fn_DGifOpenFileName DGifOpenFileName
7491 #endif /* HAVE_NTGUI */
7493 /* Reading a GIF image from memory
7494 Based on the PNG memory stuff to a certain extent. */
7496 typedef struct
7498 unsigned char *bytes;
7499 size_t len;
7500 int index;
7502 gif_memory_source;
7504 /* Make the current memory source available to gif_read_from_memory.
7505 It's done this way because not all versions of libungif support
7506 a UserData field in the GifFileType structure. */
7507 static gif_memory_source *current_gif_memory_src;
7509 static int
7510 gif_read_from_memory (file, buf, len)
7511 GifFileType *file;
7512 GifByteType *buf;
7513 int len;
7515 gif_memory_source *src = current_gif_memory_src;
7517 if (len > src->len - src->index)
7518 return -1;
7520 bcopy (src->bytes + src->index, buf, len);
7521 src->index += len;
7522 return len;
7526 /* Load GIF image IMG for use on frame F. Value is non-zero if
7527 successful. */
7529 static int interlace_start[] = {0, 4, 2, 1};
7530 static int interlace_increment[] = {8, 8, 4, 2};
7532 static int
7533 gif_load (f, img)
7534 struct frame *f;
7535 struct image *img;
7537 Lisp_Object file, specified_file;
7538 Lisp_Object specified_data;
7539 int rc, width, height, x, y, i;
7540 XImagePtr ximg;
7541 ColorMapObject *gif_color_map;
7542 unsigned long pixel_colors[256];
7543 GifFileType *gif;
7544 struct gcpro gcpro1;
7545 Lisp_Object image;
7546 int ino, image_height, image_width;
7547 gif_memory_source memsrc;
7548 unsigned char *raster;
7550 specified_file = image_spec_value (img->spec, QCfile, NULL);
7551 specified_data = image_spec_value (img->spec, QCdata, NULL);
7552 file = Qnil;
7553 GCPRO1 (file);
7555 if (NILP (specified_data))
7557 file = x_find_image_file (specified_file);
7558 if (!STRINGP (file))
7560 image_error ("Cannot find image file `%s'", specified_file, Qnil);
7561 UNGCPRO;
7562 return 0;
7565 /* Open the GIF file. Casting return value avoids a GCC warning
7566 on W32. */
7567 gif = (GifFileType *)fn_DGifOpenFileName (SDATA (file));
7568 if (gif == NULL)
7570 image_error ("Cannot open `%s'", file, Qnil);
7571 UNGCPRO;
7572 return 0;
7575 else
7577 /* Read from memory! */
7578 current_gif_memory_src = &memsrc;
7579 memsrc.bytes = SDATA (specified_data);
7580 memsrc.len = SBYTES (specified_data);
7581 memsrc.index = 0;
7583 /* Casting return value avoids a GCC warning on W32. */
7584 gif = (GifFileType *) fn_DGifOpen (&memsrc, gif_read_from_memory);
7585 if (!gif)
7587 image_error ("Cannot open memory source `%s'", img->spec, Qnil);
7588 UNGCPRO;
7589 return 0;
7593 /* Before reading entire contents, check the declared image size. */
7594 if (!check_image_size (f, gif->SWidth, gif->SHeight))
7596 image_error ("Invalid image size", Qnil, Qnil);
7597 fn_DGifCloseFile (gif);
7598 UNGCPRO;
7599 return 0;
7602 /* Read entire contents. */
7603 rc = fn_DGifSlurp (gif);
7604 if (rc == GIF_ERROR)
7606 image_error ("Error reading `%s'", img->spec, Qnil);
7607 fn_DGifCloseFile (gif);
7608 UNGCPRO;
7609 return 0;
7612 image = image_spec_value (img->spec, QCindex, NULL);
7613 ino = INTEGERP (image) ? XFASTINT (image) : 0;
7614 if (ino >= gif->ImageCount)
7616 image_error ("Invalid image number `%s' in image `%s'",
7617 image, img->spec);
7618 fn_DGifCloseFile (gif);
7619 UNGCPRO;
7620 return 0;
7623 img->corners[TOP_CORNER] = gif->SavedImages[ino].ImageDesc.Top;
7624 img->corners[LEFT_CORNER] = gif->SavedImages[ino].ImageDesc.Left;
7625 image_height = gif->SavedImages[ino].ImageDesc.Height;
7626 img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + image_height;
7627 image_width = gif->SavedImages[ino].ImageDesc.Width;
7628 img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + image_width;
7630 width = img->width = max (gif->SWidth,
7631 max (gif->Image.Left + gif->Image.Width,
7632 img->corners[RIGHT_CORNER]));
7633 height = img->height = max (gif->SHeight,
7634 max (gif->Image.Top + gif->Image.Height,
7635 img->corners[BOT_CORNER]));
7637 if (!check_image_size (f, width, height))
7639 image_error ("Invalid image size", Qnil, Qnil);
7640 fn_DGifCloseFile (gif);
7641 UNGCPRO;
7642 return 0;
7645 /* Create the X image and pixmap. */
7646 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
7648 fn_DGifCloseFile (gif);
7649 UNGCPRO;
7650 return 0;
7653 /* Allocate colors. */
7654 gif_color_map = gif->SavedImages[ino].ImageDesc.ColorMap;
7655 if (!gif_color_map)
7656 gif_color_map = gif->SColorMap;
7657 init_color_table ();
7658 bzero (pixel_colors, sizeof pixel_colors);
7660 if (gif_color_map)
7661 for (i = 0; i < gif_color_map->ColorCount; ++i)
7663 int r = gif_color_map->Colors[i].Red << 8;
7664 int g = gif_color_map->Colors[i].Green << 8;
7665 int b = gif_color_map->Colors[i].Blue << 8;
7666 pixel_colors[i] = lookup_rgb_color (f, r, g, b);
7669 #ifdef COLOR_TABLE_SUPPORT
7670 img->colors = colors_in_color_table (&img->ncolors);
7671 free_color_table ();
7672 #endif /* COLOR_TABLE_SUPPORT */
7674 /* Clear the part of the screen image that are not covered by
7675 the image from the GIF file. Full animated GIF support
7676 requires more than can be done here (see the gif89 spec,
7677 disposal methods). Let's simply assume that the part
7678 not covered by a sub-image is in the frame's background color. */
7679 for (y = 0; y < img->corners[TOP_CORNER]; ++y)
7680 for (x = 0; x < width; ++x)
7681 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7683 for (y = img->corners[BOT_CORNER]; y < height; ++y)
7684 for (x = 0; x < width; ++x)
7685 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7687 for (y = img->corners[TOP_CORNER]; y < img->corners[BOT_CORNER]; ++y)
7689 for (x = 0; x < img->corners[LEFT_CORNER]; ++x)
7690 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7691 for (x = img->corners[RIGHT_CORNER]; x < width; ++x)
7692 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7695 /* Read the GIF image into the X image. We use a local variable
7696 `raster' here because RasterBits below is a char *, and invites
7697 problems with bytes >= 0x80. */
7698 raster = (unsigned char *) gif->SavedImages[ino].RasterBits;
7700 if (gif->SavedImages[ino].ImageDesc.Interlace)
7702 int pass;
7703 int row = interlace_start[0];
7705 pass = 0;
7707 for (y = 0; y < image_height; y++)
7709 if (row >= image_height)
7711 row = interlace_start[++pass];
7712 while (row >= image_height)
7713 row = interlace_start[++pass];
7716 for (x = 0; x < image_width; x++)
7718 int i = raster[(y * image_width) + x];
7719 XPutPixel (ximg, x + img->corners[LEFT_CORNER],
7720 row + img->corners[TOP_CORNER], pixel_colors[i]);
7723 row += interlace_increment[pass];
7726 else
7728 for (y = 0; y < image_height; ++y)
7729 for (x = 0; x < image_width; ++x)
7731 int i = raster[y * image_width + x];
7732 XPutPixel (ximg, x + img->corners[LEFT_CORNER],
7733 y + img->corners[TOP_CORNER], pixel_colors[i]);
7737 /* Save GIF image extension data for `image-extension-data'.
7738 Format is (count IMAGES FUNCTION "BYTES" ...). */
7739 img->data.lisp_val = Qnil;
7740 if (gif->SavedImages[ino].ExtensionBlockCount > 0)
7742 ExtensionBlock *ext = gif->SavedImages[ino].ExtensionBlocks;
7743 for (i = 0; i < gif->SavedImages[ino].ExtensionBlockCount; i++, ext++)
7744 /* Append (... FUNCTION "BYTES") */
7745 img->data.lisp_val = Fcons (make_unibyte_string (ext->Bytes, ext->ByteCount),
7746 Fcons (make_number (ext->Function),
7747 img->data.lisp_val));
7748 img->data.lisp_val = Fnreverse (img->data.lisp_val);
7750 if (gif->ImageCount > 1)
7751 img->data.lisp_val = Fcons (Qcount,
7752 Fcons (make_number (gif->ImageCount),
7753 img->data.lisp_val));
7755 fn_DGifCloseFile (gif);
7757 /* Maybe fill in the background field while we have ximg handy. */
7758 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7759 /* Casting avoids a GCC warning. */
7760 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
7762 /* Put the image into the pixmap, then free the X image and its buffer. */
7763 x_put_x_image (f, ximg, img->pixmap, width, height);
7764 x_destroy_x_image (ximg);
7766 UNGCPRO;
7767 return 1;
7770 #else /* !HAVE_GIF */
7772 #ifdef HAVE_NS
7773 static int
7774 gif_load (struct frame *f, struct image *img)
7776 return ns_load_image(f, img,
7777 image_spec_value (img->spec, QCfile, NULL),
7778 image_spec_value (img->spec, QCdata, NULL));
7780 #endif /* HAVE_NS */
7782 #endif /* HAVE_GIF */
7786 /***********************************************************************
7788 ***********************************************************************/
7790 #if defined (HAVE_RSVG)
7792 /* Function prototypes. */
7794 static int svg_image_p P_ ((Lisp_Object object));
7795 static int svg_load P_ ((struct frame *f, struct image *img));
7797 static int svg_load_image P_ ((struct frame *, struct image *,
7798 unsigned char *, unsigned int));
7800 /* The symbol `svg' identifying images of this type. */
7802 Lisp_Object Qsvg;
7804 /* Indices of image specification fields in svg_format, below. */
7806 enum svg_keyword_index
7808 SVG_TYPE,
7809 SVG_DATA,
7810 SVG_FILE,
7811 SVG_ASCENT,
7812 SVG_MARGIN,
7813 SVG_RELIEF,
7814 SVG_ALGORITHM,
7815 SVG_HEURISTIC_MASK,
7816 SVG_MASK,
7817 SVG_BACKGROUND,
7818 SVG_LAST
7821 /* Vector of image_keyword structures describing the format
7822 of valid user-defined image specifications. */
7824 static struct image_keyword svg_format[SVG_LAST] =
7826 {":type", IMAGE_SYMBOL_VALUE, 1},
7827 {":data", IMAGE_STRING_VALUE, 0},
7828 {":file", IMAGE_STRING_VALUE, 0},
7829 {":ascent", IMAGE_ASCENT_VALUE, 0},
7830 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
7831 {":relief", IMAGE_INTEGER_VALUE, 0},
7832 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7833 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7834 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7835 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
7838 /* Structure describing the image type `svg'. Its the same type of
7839 structure defined for all image formats, handled by emacs image
7840 functions. See struct image_type in dispextern.h. */
7842 static struct image_type svg_type =
7844 /* An identifier showing that this is an image structure for the SVG format. */
7845 &Qsvg,
7846 /* Handle to a function that can be used to identify a SVG file. */
7847 svg_image_p,
7848 /* Handle to function used to load a SVG file. */
7849 svg_load,
7850 /* Handle to function to free sresources for SVG. */
7851 x_clear_image,
7852 /* An internal field to link to the next image type in a list of
7853 image types, will be filled in when registering the format. */
7854 NULL
7858 /* Return non-zero if OBJECT is a valid SVG image specification. Do
7859 this by calling parse_image_spec and supplying the keywords that
7860 identify the SVG format. */
7862 static int
7863 svg_image_p (object)
7864 Lisp_Object object;
7866 struct image_keyword fmt[SVG_LAST];
7867 bcopy (svg_format, fmt, sizeof fmt);
7869 if (!parse_image_spec (object, fmt, SVG_LAST, Qsvg))
7870 return 0;
7872 /* Must specify either the :data or :file keyword. */
7873 return fmt[SVG_FILE].count + fmt[SVG_DATA].count == 1;
7876 #include <librsvg/rsvg.h>
7878 #ifdef HAVE_NTGUI
7880 /* SVG library functions. */
7881 DEF_IMGLIB_FN (rsvg_handle_new);
7882 DEF_IMGLIB_FN (rsvg_handle_get_dimensions);
7883 DEF_IMGLIB_FN (rsvg_handle_write);
7884 DEF_IMGLIB_FN (rsvg_handle_close);
7885 DEF_IMGLIB_FN (rsvg_handle_get_pixbuf);
7886 DEF_IMGLIB_FN (rsvg_handle_free);
7888 DEF_IMGLIB_FN (gdk_pixbuf_get_width);
7889 DEF_IMGLIB_FN (gdk_pixbuf_get_height);
7890 DEF_IMGLIB_FN (gdk_pixbuf_get_pixels);
7891 DEF_IMGLIB_FN (gdk_pixbuf_get_rowstride);
7892 DEF_IMGLIB_FN (gdk_pixbuf_get_colorspace);
7893 DEF_IMGLIB_FN (gdk_pixbuf_get_n_channels);
7894 DEF_IMGLIB_FN (gdk_pixbuf_get_has_alpha);
7895 DEF_IMGLIB_FN (gdk_pixbuf_get_bits_per_sample);
7897 DEF_IMGLIB_FN (g_type_init);
7898 DEF_IMGLIB_FN (g_object_unref);
7899 DEF_IMGLIB_FN (g_error_free);
7901 Lisp_Object Qgdk_pixbuf, Qglib;
7903 static int
7904 init_svg_functions (Lisp_Object libraries)
7906 HMODULE library, gdklib, glib;
7908 if (!(glib = w32_delayed_load (libraries, Qglib))
7909 || !(gdklib = w32_delayed_load (libraries, Qgdk_pixbuf))
7910 || !(library = w32_delayed_load (libraries, Qsvg)))
7911 return 0;
7913 LOAD_IMGLIB_FN (library, rsvg_handle_new);
7914 LOAD_IMGLIB_FN (library, rsvg_handle_get_dimensions);
7915 LOAD_IMGLIB_FN (library, rsvg_handle_write);
7916 LOAD_IMGLIB_FN (library, rsvg_handle_close);
7917 LOAD_IMGLIB_FN (library, rsvg_handle_get_pixbuf);
7918 LOAD_IMGLIB_FN (library, rsvg_handle_free);
7920 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_width);
7921 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_height);
7922 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_pixels);
7923 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_rowstride);
7924 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_colorspace);
7925 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_n_channels);
7926 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_has_alpha);
7927 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_bits_per_sample);
7929 LOAD_IMGLIB_FN (glib, g_type_init);
7930 LOAD_IMGLIB_FN (glib, g_object_unref);
7931 LOAD_IMGLIB_FN (glib, g_error_free);
7932 return 1;
7935 #else
7936 /* The following aliases for library functions allow dynamic loading
7937 to be used on some platforms. */
7938 #define fn_rsvg_handle_new rsvg_handle_new
7939 #define fn_rsvg_handle_get_dimensions rsvg_handle_get_dimensions
7940 #define fn_rsvg_handle_write rsvg_handle_write
7941 #define fn_rsvg_handle_close rsvg_handle_close
7942 #define fn_rsvg_handle_get_pixbuf rsvg_handle_get_pixbuf
7943 #define fn_rsvg_handle_free rsvg_handle_free
7945 #define fn_gdk_pixbuf_get_width gdk_pixbuf_get_width
7946 #define fn_gdk_pixbuf_get_height gdk_pixbuf_get_height
7947 #define fn_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels
7948 #define fn_gdk_pixbuf_get_rowstride gdk_pixbuf_get_rowstride
7949 #define fn_gdk_pixbuf_get_colorspace gdk_pixbuf_get_colorspace
7950 #define fn_gdk_pixbuf_get_n_channels gdk_pixbuf_get_n_channels
7951 #define fn_gdk_pixbuf_get_has_alpha gdk_pixbuf_get_has_alpha
7952 #define fn_gdk_pixbuf_get_bits_per_sample gdk_pixbuf_get_bits_per_sample
7954 #define fn_g_type_init g_type_init
7955 #define fn_g_object_unref g_object_unref
7956 #define fn_g_error_free g_error_free
7957 #endif /* !HAVE_NTGUI */
7959 /* Load SVG image IMG for use on frame F. Value is non-zero if
7960 successful. this function will go into the svg_type structure, and
7961 the prototype thus needs to be compatible with that structure. */
7963 static int
7964 svg_load (f, img)
7965 struct frame *f;
7966 struct image *img;
7968 int success_p = 0;
7969 Lisp_Object file_name;
7971 /* If IMG->spec specifies a file name, create a non-file spec from it. */
7972 file_name = image_spec_value (img->spec, QCfile, NULL);
7973 if (STRINGP (file_name))
7975 Lisp_Object file;
7976 unsigned char *contents;
7977 int size;
7978 struct gcpro gcpro1;
7980 file = x_find_image_file (file_name);
7981 GCPRO1 (file);
7982 if (!STRINGP (file))
7984 image_error ("Cannot find image file `%s'", file_name, Qnil);
7985 UNGCPRO;
7986 return 0;
7989 /* Read the entire file into memory. */
7990 contents = slurp_file (SDATA (file), &size);
7991 if (contents == NULL)
7993 image_error ("Error loading SVG image `%s'", img->spec, Qnil);
7994 UNGCPRO;
7995 return 0;
7997 /* If the file was slurped into memory properly, parse it. */
7998 success_p = svg_load_image (f, img, contents, size);
7999 xfree (contents);
8000 UNGCPRO;
8002 /* Else its not a file, its a lisp object. Load the image from a
8003 lisp object rather than a file. */
8004 else
8006 Lisp_Object data;
8008 data = image_spec_value (img->spec, QCdata, NULL);
8009 success_p = svg_load_image (f, img, SDATA (data), SBYTES (data));
8012 return success_p;
8015 /* svg_load_image is a helper function for svg_load, which does the
8016 actual loading given contents and size, apart from frame and image
8017 structures, passed from svg_load.
8019 Uses librsvg to do most of the image processing.
8021 Returns non-zero when successful. */
8022 static int
8023 svg_load_image (f, img, contents, size)
8024 /* Pointer to emacs frame structure. */
8025 struct frame *f;
8026 /* Pointer to emacs image structure. */
8027 struct image *img;
8028 /* String containing the SVG XML data to be parsed. */
8029 unsigned char *contents;
8030 /* Size of data in bytes. */
8031 unsigned int size;
8033 RsvgHandle *rsvg_handle;
8034 RsvgDimensionData dimension_data;
8035 GError *error = NULL;
8036 GdkPixbuf *pixbuf;
8037 int width;
8038 int height;
8039 const guint8 *pixels;
8040 int rowstride;
8041 XImagePtr ximg;
8042 Lisp_Object specified_bg;
8043 XColor background;
8044 int x;
8045 int y;
8047 /* g_type_init is a glib function that must be called prior to using
8048 gnome type library functions. */
8049 fn_g_type_init ();
8050 /* Make a handle to a new rsvg object. */
8051 rsvg_handle = fn_rsvg_handle_new ();
8053 /* Parse the contents argument and fill in the rsvg_handle. */
8054 fn_rsvg_handle_write (rsvg_handle, contents, size, &error);
8055 if (error) goto rsvg_error;
8057 /* The parsing is complete, rsvg_handle is ready to used, close it
8058 for further writes. */
8059 fn_rsvg_handle_close (rsvg_handle, &error);
8060 if (error) goto rsvg_error;
8062 fn_rsvg_handle_get_dimensions (rsvg_handle, &dimension_data);
8063 if (! check_image_size (f, dimension_data.width, dimension_data.height))
8064 goto rsvg_error;
8066 /* We can now get a valid pixel buffer from the svg file, if all
8067 went ok. */
8068 pixbuf = fn_rsvg_handle_get_pixbuf (rsvg_handle);
8069 if (!pixbuf) goto rsvg_error;
8070 fn_g_object_unref (rsvg_handle);
8072 /* Extract some meta data from the svg handle. */
8073 width = fn_gdk_pixbuf_get_width (pixbuf);
8074 height = fn_gdk_pixbuf_get_height (pixbuf);
8075 pixels = fn_gdk_pixbuf_get_pixels (pixbuf);
8076 rowstride = fn_gdk_pixbuf_get_rowstride (pixbuf);
8078 /* Validate the svg meta data. */
8079 eassert (fn_gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB);
8080 eassert (fn_gdk_pixbuf_get_n_channels (pixbuf) == 4);
8081 eassert (fn_gdk_pixbuf_get_has_alpha (pixbuf));
8082 eassert (fn_gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
8084 /* Try to create a x pixmap to hold the svg pixmap. */
8085 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
8087 fn_g_object_unref (pixbuf);
8088 return 0;
8091 init_color_table ();
8093 /* Handle alpha channel by combining the image with a background
8094 color. */
8095 specified_bg = image_spec_value (img->spec, QCbackground, NULL);
8096 if (STRINGP (specified_bg)
8097 && x_defined_color (f, SDATA (specified_bg), &background, 0))
8099 background.red >>= 8;
8100 background.green >>= 8;
8101 background.blue >>= 8;
8103 else
8105 #ifdef HAVE_X_WINDOWS
8106 background.pixel = FRAME_BACKGROUND_PIXEL (f);
8107 x_query_color (f, &background);
8109 /* SVG pixmaps specify transparency in the last byte, so right
8110 shift 8 bits to get rid of it, since emacs doesn't support
8111 transparency. */
8112 background.red >>= 8;
8113 background.green >>= 8;
8114 background.blue >>= 8;
8115 #elif defined (HAVE_NTGUI)
8116 background.pixel = FRAME_BACKGROUND_PIXEL (f);
8117 #if 0 /* W32 TODO : Colormap support. */
8118 x_query_color (f, &background);
8119 #endif
8121 /* SVG pixmaps specify transparency in the last byte, so right
8122 shift 8 bits to get rid of it, since emacs doesn't support
8123 transparency. */
8124 background.red >>= 8;
8125 background.green >>= 8;
8126 background.blue >>= 8;
8127 #else /* not HAVE_X_WINDOWS*/
8128 #error FIXME
8129 #endif
8132 /* This loop handles opacity values, since Emacs assumes
8133 non-transparent images. Each pixel must be "flattened" by
8134 calculating the resulting color, given the transparency of the
8135 pixel, and the image background color. */
8136 for (y = 0; y < height; ++y)
8138 for (x = 0; x < width; ++x)
8140 unsigned red;
8141 unsigned green;
8142 unsigned blue;
8143 unsigned opacity;
8145 red = *pixels++;
8146 green = *pixels++;
8147 blue = *pixels++;
8148 opacity = *pixels++;
8150 red = ((red * opacity)
8151 + (background.red * ((1 << 8) - opacity)));
8152 green = ((green * opacity)
8153 + (background.green * ((1 << 8) - opacity)));
8154 blue = ((blue * opacity)
8155 + (background.blue * ((1 << 8) - opacity)));
8157 XPutPixel (ximg, x, y, lookup_rgb_color (f, red, green, blue));
8160 pixels += rowstride - 4 * width;
8163 #ifdef COLOR_TABLE_SUPPORT
8164 /* Remember colors allocated for this image. */
8165 img->colors = colors_in_color_table (&img->ncolors);
8166 free_color_table ();
8167 #endif /* COLOR_TABLE_SUPPORT */
8169 fn_g_object_unref (pixbuf);
8171 img->width = width;
8172 img->height = height;
8174 /* Maybe fill in the background field while we have ximg handy.
8175 Casting avoids a GCC warning. */
8176 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
8178 /* Put the image into the pixmap, then free the X image and its
8179 buffer. */
8180 x_put_x_image (f, ximg, img->pixmap, width, height);
8181 x_destroy_x_image (ximg);
8183 return 1;
8185 rsvg_error:
8186 fn_g_object_unref (rsvg_handle);
8187 /* FIXME: Use error->message so the user knows what is the actual
8188 problem with the image. */
8189 image_error ("Error parsing SVG image `%s'", img->spec, Qnil);
8190 fn_g_error_free (error);
8191 return 0;
8194 #endif /* defined (HAVE_RSVG) */
8199 /***********************************************************************
8200 Ghostscript
8201 ***********************************************************************/
8203 #ifdef HAVE_X_WINDOWS
8204 #define HAVE_GHOSTSCRIPT 1
8205 #endif /* HAVE_X_WINDOWS */
8207 /* The symbol `postscript' identifying images of this type. */
8209 Lisp_Object Qpostscript;
8211 #ifdef HAVE_GHOSTSCRIPT
8213 static int gs_image_p P_ ((Lisp_Object object));
8214 static int gs_load P_ ((struct frame *f, struct image *img));
8215 static void gs_clear_image P_ ((struct frame *f, struct image *img));
8217 /* Keyword symbols. */
8219 Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height;
8221 /* Indices of image specification fields in gs_format, below. */
8223 enum gs_keyword_index
8225 GS_TYPE,
8226 GS_PT_WIDTH,
8227 GS_PT_HEIGHT,
8228 GS_FILE,
8229 GS_LOADER,
8230 GS_BOUNDING_BOX,
8231 GS_ASCENT,
8232 GS_MARGIN,
8233 GS_RELIEF,
8234 GS_ALGORITHM,
8235 GS_HEURISTIC_MASK,
8236 GS_MASK,
8237 GS_BACKGROUND,
8238 GS_LAST
8241 /* Vector of image_keyword structures describing the format
8242 of valid user-defined image specifications. */
8244 static struct image_keyword gs_format[GS_LAST] =
8246 {":type", IMAGE_SYMBOL_VALUE, 1},
8247 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE, 1},
8248 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE, 1},
8249 {":file", IMAGE_STRING_VALUE, 1},
8250 {":loader", IMAGE_FUNCTION_VALUE, 0},
8251 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1},
8252 {":ascent", IMAGE_ASCENT_VALUE, 0},
8253 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
8254 {":relief", IMAGE_INTEGER_VALUE, 0},
8255 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8256 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8257 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8258 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
8261 /* Structure describing the image type `ghostscript'. */
8263 static struct image_type gs_type =
8265 &Qpostscript,
8266 gs_image_p,
8267 gs_load,
8268 gs_clear_image,
8269 NULL
8273 /* Free X resources of Ghostscript image IMG which is used on frame F. */
8275 static void
8276 gs_clear_image (f, img)
8277 struct frame *f;
8278 struct image *img;
8280 /* IMG->data.ptr_val may contain a recorded colormap. */
8281 xfree (img->data.ptr_val);
8282 x_clear_image (f, img);
8286 /* Return non-zero if OBJECT is a valid Ghostscript image
8287 specification. */
8289 static int
8290 gs_image_p (object)
8291 Lisp_Object object;
8293 struct image_keyword fmt[GS_LAST];
8294 Lisp_Object tem;
8295 int i;
8297 bcopy (gs_format, fmt, sizeof fmt);
8299 if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript))
8300 return 0;
8302 /* Bounding box must be a list or vector containing 4 integers. */
8303 tem = fmt[GS_BOUNDING_BOX].value;
8304 if (CONSP (tem))
8306 for (i = 0; i < 4; ++i, tem = XCDR (tem))
8307 if (!CONSP (tem) || !INTEGERP (XCAR (tem)))
8308 return 0;
8309 if (!NILP (tem))
8310 return 0;
8312 else if (VECTORP (tem))
8314 if (XVECTOR (tem)->size != 4)
8315 return 0;
8316 for (i = 0; i < 4; ++i)
8317 if (!INTEGERP (XVECTOR (tem)->contents[i]))
8318 return 0;
8320 else
8321 return 0;
8323 return 1;
8327 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
8328 if successful. */
8330 static int
8331 gs_load (f, img)
8332 struct frame *f;
8333 struct image *img;
8335 char buffer[100];
8336 Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width;
8337 struct gcpro gcpro1, gcpro2;
8338 Lisp_Object frame;
8339 double in_width, in_height;
8340 Lisp_Object pixel_colors = Qnil;
8342 /* Compute pixel size of pixmap needed from the given size in the
8343 image specification. Sizes in the specification are in pt. 1 pt
8344 = 1/72 in, xdpi and ydpi are stored in the frame's X display
8345 info. */
8346 pt_width = image_spec_value (img->spec, QCpt_width, NULL);
8347 in_width = XFASTINT (pt_width) / 72.0;
8348 img->width = in_width * FRAME_X_DISPLAY_INFO (f)->resx;
8349 pt_height = image_spec_value (img->spec, QCpt_height, NULL);
8350 in_height = XFASTINT (pt_height) / 72.0;
8351 img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy;
8353 if (!check_image_size (f, img->width, img->height))
8355 image_error ("Invalid image size", Qnil, Qnil);
8356 return 0;
8359 /* Create the pixmap. */
8360 xassert (img->pixmap == NO_PIXMAP);
8362 /* Only W32 version did BLOCK_INPUT here. ++kfs */
8363 BLOCK_INPUT;
8364 img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
8365 img->width, img->height,
8366 DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
8367 UNBLOCK_INPUT;
8369 if (!img->pixmap)
8371 image_error ("Unable to create pixmap for `%s'", img->spec, Qnil);
8372 return 0;
8375 /* Call the loader to fill the pixmap. It returns a process object
8376 if successful. We do not record_unwind_protect here because
8377 other places in redisplay like calling window scroll functions
8378 don't either. Let the Lisp loader use `unwind-protect' instead. */
8379 GCPRO2 (window_and_pixmap_id, pixel_colors);
8381 sprintf (buffer, "%lu %lu",
8382 (unsigned long) FRAME_X_WINDOW (f),
8383 (unsigned long) img->pixmap);
8384 window_and_pixmap_id = build_string (buffer);
8386 sprintf (buffer, "%lu %lu",
8387 FRAME_FOREGROUND_PIXEL (f),
8388 FRAME_BACKGROUND_PIXEL (f));
8389 pixel_colors = build_string (buffer);
8391 XSETFRAME (frame, f);
8392 loader = image_spec_value (img->spec, QCloader, NULL);
8393 if (NILP (loader))
8394 loader = intern ("gs-load-image");
8396 img->data.lisp_val = call6 (loader, frame, img->spec,
8397 make_number (img->width),
8398 make_number (img->height),
8399 window_and_pixmap_id,
8400 pixel_colors);
8401 UNGCPRO;
8402 return PROCESSP (img->data.lisp_val);
8406 /* Kill the Ghostscript process that was started to fill PIXMAP on
8407 frame F. Called from XTread_socket when receiving an event
8408 telling Emacs that Ghostscript has finished drawing. */
8410 void
8411 x_kill_gs_process (pixmap, f)
8412 Pixmap pixmap;
8413 struct frame *f;
8415 struct image_cache *c = FRAME_IMAGE_CACHE (f);
8416 int class, i;
8417 struct image *img;
8419 /* Find the image containing PIXMAP. */
8420 for (i = 0; i < c->used; ++i)
8421 if (c->images[i]->pixmap == pixmap)
8422 break;
8424 /* Should someone in between have cleared the image cache, for
8425 instance, give up. */
8426 if (i == c->used)
8427 return;
8429 /* Kill the GS process. We should have found PIXMAP in the image
8430 cache and its image should contain a process object. */
8431 img = c->images[i];
8432 xassert (PROCESSP (img->data.lisp_val));
8433 Fkill_process (img->data.lisp_val, Qnil);
8434 img->data.lisp_val = Qnil;
8436 #if defined (HAVE_X_WINDOWS)
8438 /* On displays with a mutable colormap, figure out the colors
8439 allocated for the image by looking at the pixels of an XImage for
8440 img->pixmap. */
8441 class = FRAME_X_VISUAL (f)->class;
8442 if (class != StaticColor && class != StaticGray && class != TrueColor)
8444 XImagePtr ximg;
8446 BLOCK_INPUT;
8448 /* Try to get an XImage for img->pixmep. */
8449 ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
8450 0, 0, img->width, img->height, ~0, ZPixmap);
8451 if (ximg)
8453 int x, y;
8455 /* Initialize the color table. */
8456 init_color_table ();
8458 /* For each pixel of the image, look its color up in the
8459 color table. After having done so, the color table will
8460 contain an entry for each color used by the image. */
8461 for (y = 0; y < img->height; ++y)
8462 for (x = 0; x < img->width; ++x)
8464 unsigned long pixel = XGetPixel (ximg, x, y);
8465 lookup_pixel_color (f, pixel);
8468 /* Record colors in the image. Free color table and XImage. */
8469 #ifdef COLOR_TABLE_SUPPORT
8470 img->colors = colors_in_color_table (&img->ncolors);
8471 free_color_table ();
8472 #endif
8473 XDestroyImage (ximg);
8475 #if 0 /* This doesn't seem to be the case. If we free the colors
8476 here, we get a BadAccess later in x_clear_image when
8477 freeing the colors. */
8478 /* We have allocated colors once, but Ghostscript has also
8479 allocated colors on behalf of us. So, to get the
8480 reference counts right, free them once. */
8481 if (img->ncolors)
8482 x_free_colors (f, img->colors, img->ncolors);
8483 #endif
8485 else
8486 image_error ("Cannot get X image of `%s'; colors will not be freed",
8487 img->spec, Qnil);
8489 UNBLOCK_INPUT;
8491 #endif /* HAVE_X_WINDOWS */
8493 /* Now that we have the pixmap, compute mask and transform the
8494 image if requested. */
8495 BLOCK_INPUT;
8496 postprocess_image (f, img);
8497 UNBLOCK_INPUT;
8500 #endif /* HAVE_GHOSTSCRIPT */
8503 /***********************************************************************
8504 Tests
8505 ***********************************************************************/
8507 #if GLYPH_DEBUG
8509 DEFUN ("imagep", Fimagep, Simagep, 1, 1, 0,
8510 doc: /* Value is non-nil if SPEC is a valid image specification. */)
8511 (spec)
8512 Lisp_Object spec;
8514 return valid_image_p (spec) ? Qt : Qnil;
8518 DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
8519 (spec)
8520 Lisp_Object spec;
8522 int id = -1;
8524 if (valid_image_p (spec))
8525 id = lookup_image (SELECTED_FRAME (), spec);
8527 debug_print (spec);
8528 return make_number (id);
8531 #endif /* GLYPH_DEBUG != 0 */
8534 /***********************************************************************
8535 Initialization
8536 ***********************************************************************/
8538 #ifdef HAVE_NTGUI
8539 /* Image types that rely on external libraries are loaded dynamically
8540 if the library is available. */
8541 #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8542 define_image_type (image_type, init_lib_fn (libraries))
8543 #else
8544 #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8545 define_image_type (image_type, 1)
8546 #endif /* HAVE_NTGUI */
8548 DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2, 2, 0,
8549 doc: /* Initialize image library implementing image type TYPE.
8550 Return non-nil if TYPE is a supported image type.
8552 Image types pbm and xbm are prebuilt; other types are loaded here.
8553 Libraries to load are specified in alist LIBRARIES (usually, the value
8554 of `image-library-alist', which see). */)
8555 (type, libraries)
8556 Lisp_Object type, libraries;
8558 Lisp_Object tested;
8560 /* Don't try to reload the library. */
8561 tested = Fassq (type, Vimage_type_cache);
8562 if (CONSP (tested))
8563 return XCDR (tested);
8565 #if defined (HAVE_XPM) || defined (HAVE_NS)
8566 if (EQ (type, Qxpm))
8567 return CHECK_LIB_AVAILABLE (&xpm_type, init_xpm_functions, libraries);
8568 #endif
8570 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8571 if (EQ (type, Qjpeg))
8572 return CHECK_LIB_AVAILABLE (&jpeg_type, init_jpeg_functions, libraries);
8573 #endif
8575 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8576 if (EQ (type, Qtiff))
8577 return CHECK_LIB_AVAILABLE (&tiff_type, init_tiff_functions, libraries);
8578 #endif
8580 #if defined (HAVE_GIF) || defined (HAVE_NS)
8581 if (EQ (type, Qgif))
8582 return CHECK_LIB_AVAILABLE (&gif_type, init_gif_functions, libraries);
8583 #endif
8585 #if defined (HAVE_PNG) || defined (HAVE_NS)
8586 if (EQ (type, Qpng))
8587 return CHECK_LIB_AVAILABLE (&png_type, init_png_functions, libraries);
8588 #endif
8590 #if defined (HAVE_RSVG)
8591 if (EQ (type, Qsvg))
8592 return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries);
8593 #endif
8595 #ifdef HAVE_GHOSTSCRIPT
8596 if (EQ (type, Qpostscript))
8597 return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries);
8598 #endif
8600 /* If the type is not recognized, avoid testing it ever again. */
8601 CACHE_IMAGE_TYPE (type, Qnil);
8602 return Qnil;
8605 void
8606 syms_of_image ()
8608 extern Lisp_Object Qrisky_local_variable; /* Syms_of_xdisp has already run. */
8610 /* Initialize this only once, since that's what we do with Vimage_types
8611 and they are supposed to be in sync. Initializing here gives correct
8612 operation on GNU/Linux of calling dump-emacs after loading some images. */
8613 image_types = NULL;
8615 /* Must be defined now becase we're going to update it below, while
8616 defining the supported image types. */
8617 DEFVAR_LISP ("image-types", &Vimage_types,
8618 doc: /* List of potentially supported image types.
8619 Each element of the list is a symbol for an image type, like 'jpeg or 'png.
8620 To check whether it is really supported, use `image-type-available-p'. */);
8621 Vimage_types = Qnil;
8623 DEFVAR_LISP ("image-library-alist", &Vimage_library_alist,
8624 doc: /* Alist of image types vs external libraries needed to display them.
8626 Each element is a list (IMAGE-TYPE LIBRARY...), where the car is a symbol
8627 representing a supported image type, and the rest are strings giving
8628 alternate filenames for the corresponding external libraries.
8630 Emacs tries to load the libraries in the order they appear on the
8631 list; if none is loaded, the running session of Emacs won't
8632 support the image type. Types 'pbm and 'xbm don't need to be
8633 listed; they are always supported. */);
8634 Vimage_library_alist = Qnil;
8635 Fput (intern ("image-library-alist"), Qrisky_local_variable, Qt);
8637 DEFVAR_LISP ("max-image-size", &Vmax_image_size,
8638 doc: /* Maximum size of images.
8639 Emacs will not load an image into memory if its pixel width or
8640 pixel height exceeds this limit.
8642 If the value is an integer, it directly specifies the maximum
8643 image height and width, measured in pixels. If it is a floating
8644 point number, it specifies the maximum image height and width
8645 as a ratio to the frame height and width. If the value is
8646 non-numeric, there is no explicit limit on the size of images. */);
8647 Vmax_image_size = make_float (MAX_IMAGE_SIZE);
8649 Vimage_type_cache = Qnil;
8650 staticpro (&Vimage_type_cache);
8652 Qpbm = intern ("pbm");
8653 staticpro (&Qpbm);
8654 ADD_IMAGE_TYPE (Qpbm);
8656 Qxbm = intern ("xbm");
8657 staticpro (&Qxbm);
8658 ADD_IMAGE_TYPE (Qxbm);
8660 define_image_type (&xbm_type, 1);
8661 define_image_type (&pbm_type, 1);
8663 Qcount = intern ("count");
8664 staticpro (&Qcount);
8666 QCascent = intern (":ascent");
8667 staticpro (&QCascent);
8668 QCmargin = intern (":margin");
8669 staticpro (&QCmargin);
8670 QCrelief = intern (":relief");
8671 staticpro (&QCrelief);
8672 QCconversion = intern (":conversion");
8673 staticpro (&QCconversion);
8674 QCcolor_symbols = intern (":color-symbols");
8675 staticpro (&QCcolor_symbols);
8676 QCheuristic_mask = intern (":heuristic-mask");
8677 staticpro (&QCheuristic_mask);
8678 QCindex = intern (":index");
8679 staticpro (&QCindex);
8680 QCmatrix = intern (":matrix");
8681 staticpro (&QCmatrix);
8682 QCcolor_adjustment = intern (":color-adjustment");
8683 staticpro (&QCcolor_adjustment);
8684 QCmask = intern (":mask");
8685 staticpro (&QCmask);
8687 Qlaplace = intern ("laplace");
8688 staticpro (&Qlaplace);
8689 Qemboss = intern ("emboss");
8690 staticpro (&Qemboss);
8691 Qedge_detection = intern ("edge-detection");
8692 staticpro (&Qedge_detection);
8693 Qheuristic = intern ("heuristic");
8694 staticpro (&Qheuristic);
8696 Qpostscript = intern ("postscript");
8697 staticpro (&Qpostscript);
8698 #ifdef HAVE_GHOSTSCRIPT
8699 ADD_IMAGE_TYPE (Qpostscript);
8700 QCloader = intern (":loader");
8701 staticpro (&QCloader);
8702 QCbounding_box = intern (":bounding-box");
8703 staticpro (&QCbounding_box);
8704 QCpt_width = intern (":pt-width");
8705 staticpro (&QCpt_width);
8706 QCpt_height = intern (":pt-height");
8707 staticpro (&QCpt_height);
8708 #endif /* HAVE_GHOSTSCRIPT */
8710 #if defined (HAVE_XPM) || defined (HAVE_NS)
8711 Qxpm = intern ("xpm");
8712 staticpro (&Qxpm);
8713 ADD_IMAGE_TYPE (Qxpm);
8714 #endif
8716 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8717 Qjpeg = intern ("jpeg");
8718 staticpro (&Qjpeg);
8719 ADD_IMAGE_TYPE (Qjpeg);
8720 #endif
8722 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8723 Qtiff = intern ("tiff");
8724 staticpro (&Qtiff);
8725 ADD_IMAGE_TYPE (Qtiff);
8726 #endif
8728 #if defined (HAVE_GIF) || defined (HAVE_NS)
8729 Qgif = intern ("gif");
8730 staticpro (&Qgif);
8731 ADD_IMAGE_TYPE (Qgif);
8732 #endif
8734 #if defined (HAVE_PNG) || defined (HAVE_NS)
8735 Qpng = intern ("png");
8736 staticpro (&Qpng);
8737 ADD_IMAGE_TYPE (Qpng);
8738 #endif
8740 #if defined (HAVE_RSVG)
8741 Qsvg = intern ("svg");
8742 staticpro (&Qsvg);
8743 ADD_IMAGE_TYPE (Qsvg);
8744 #ifdef HAVE_NTGUI
8745 Qgdk_pixbuf = intern ("gdk-pixbuf");
8746 staticpro (&Qgdk_pixbuf);
8747 Qglib = intern ("glib");
8748 staticpro (&Qglib);
8749 #endif /* HAVE_NTGUI */
8750 #endif /* HAVE_RSVG */
8752 defsubr (&Sinit_image_library);
8753 defsubr (&Sclear_image_cache);
8754 defsubr (&Simage_refresh);
8755 defsubr (&Simage_size);
8756 defsubr (&Simage_mask_p);
8757 defsubr (&Simage_extension_data);
8759 #if GLYPH_DEBUG
8760 defsubr (&Simagep);
8761 defsubr (&Slookup_image);
8762 #endif
8764 DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images,
8765 doc: /* Non-nil means always draw a cross over disabled images.
8766 Disabled images are those having a `:conversion disabled' property.
8767 A cross is always drawn on black & white displays. */);
8768 cross_disabled_images = 0;
8770 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
8771 doc: /* List of directories to search for window system bitmap files. */);
8772 Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS);
8774 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay,
8775 doc: /* Time after which cached images are removed from the cache.
8776 When an image has not been displayed this many seconds, remove it
8777 from the image cache. Value must be an integer or nil with nil
8778 meaning don't clear the cache. */);
8779 Vimage_cache_eviction_delay = make_number (30 * 60);
8782 void
8783 init_image ()
8787 /* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9
8788 (do not change this comment) */