(proced-sort-header): New face.
[emacs.git] / src / image.c
blob7ce5b9b2e08bb56746616b4695ff5c14cb59ab45
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 #ifdef HAVE_NS
1626 if (img->background_valid)
1627 ns_free_indexed_color(img->background);
1628 #endif
1629 img->background_valid = 0;
1632 if (mask_p && img->mask)
1634 Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
1635 img->mask = NO_PIXMAP;
1636 img->background_transparent_valid = 0;
1639 if (colors_p && img->ncolors)
1641 /* W32_TODO: color table support. */
1642 #ifdef HAVE_X_WINDOWS
1643 x_free_colors (f, img->colors, img->ncolors);
1644 #endif /* HAVE_X_WINDOWS */
1645 xfree (img->colors);
1646 img->colors = NULL;
1647 img->ncolors = 0;
1652 /* Free X resources of image IMG which is used on frame F. */
1654 static void
1655 x_clear_image (f, img)
1656 struct frame *f;
1657 struct image *img;
1659 BLOCK_INPUT;
1660 x_clear_image_1 (f, img, 1, 1, 1);
1661 UNBLOCK_INPUT;
1665 /* Allocate color COLOR_NAME for image IMG on frame F. If color
1666 cannot be allocated, use DFLT. Add a newly allocated color to
1667 IMG->colors, so that it can be freed again. Value is the pixel
1668 color. */
1670 static unsigned long
1671 x_alloc_image_color (f, img, color_name, dflt)
1672 struct frame *f;
1673 struct image *img;
1674 Lisp_Object color_name;
1675 unsigned long dflt;
1677 XColor color;
1678 unsigned long result;
1680 xassert (STRINGP (color_name));
1682 if (x_defined_color (f, SDATA (color_name), &color, 1))
1684 /* This isn't called frequently so we get away with simply
1685 reallocating the color vector to the needed size, here. */
1686 ++img->ncolors;
1687 img->colors =
1688 (unsigned long *) xrealloc (img->colors,
1689 img->ncolors * sizeof *img->colors);
1690 img->colors[img->ncolors - 1] = color.pixel;
1691 result = color.pixel;
1693 else
1694 result = dflt;
1696 return result;
1701 /***********************************************************************
1702 Image Cache
1703 ***********************************************************************/
1705 static struct image *search_image_cache P_ ((struct frame *, Lisp_Object, unsigned));
1706 static void cache_image P_ ((struct frame *f, struct image *img));
1707 static void postprocess_image P_ ((struct frame *, struct image *));
1709 /* Return a new, initialized image cache that is allocated from the
1710 heap. Call free_image_cache to free an image cache. */
1712 struct image_cache *
1713 make_image_cache ()
1715 struct image_cache *c = (struct image_cache *) xmalloc (sizeof *c);
1716 int size;
1718 bzero (c, sizeof *c);
1719 c->size = 50;
1720 c->images = (struct image **) xmalloc (c->size * sizeof *c->images);
1721 size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
1722 c->buckets = (struct image **) xmalloc (size);
1723 bzero (c->buckets, size);
1724 return c;
1728 /* Find an image matching SPEC in the cache, and return it. If no
1729 image is found, return NULL. */
1730 static struct image *
1731 search_image_cache (f, spec, hash)
1732 struct frame *f;
1733 Lisp_Object spec;
1734 unsigned hash;
1736 struct image *img;
1737 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1738 int i = hash % IMAGE_CACHE_BUCKETS_SIZE;
1740 if (!c) return NULL;
1742 /* If the image spec does not specify a background color, the cached
1743 image must have the same background color as the current frame.
1744 The foreground color must also match, for the sake of monochrome
1745 images.
1747 In fact, we could ignore the foreground color matching condition
1748 for color images, or if the image spec specifies :foreground;
1749 similarly we could ignore the background color matching condition
1750 for formats that don't use transparency (such as jpeg), or if the
1751 image spec specifies :background. However, the extra memory
1752 usage is probably negligible in practice, so we don't bother. */
1754 for (img = c->buckets[i]; img; img = img->next)
1755 if (img->hash == hash
1756 && !NILP (Fequal (img->spec, spec))
1757 && img->frame_foreground == FRAME_FOREGROUND_PIXEL (f)
1758 && img->frame_background == FRAME_BACKGROUND_PIXEL (f))
1759 break;
1760 return img;
1764 /* Search frame F for an image with spec SPEC, and free it. */
1766 static void
1767 uncache_image (f, spec)
1768 struct frame *f;
1769 Lisp_Object spec;
1771 struct image *img = search_image_cache (f, spec, sxhash (spec, 0));
1772 if (img)
1773 free_image (f, img);
1777 /* Free image cache of frame F. Be aware that X frames share images
1778 caches. */
1780 void
1781 free_image_cache (f)
1782 struct frame *f;
1784 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1785 if (c)
1787 int i;
1789 /* Cache should not be referenced by any frame when freed. */
1790 xassert (c->refcount == 0);
1792 for (i = 0; i < c->used; ++i)
1793 free_image (f, c->images[i]);
1794 xfree (c->images);
1795 xfree (c->buckets);
1796 xfree (c);
1797 FRAME_IMAGE_CACHE (f) = NULL;
1802 /* Clear image cache of frame F. FILTER=t means free all images.
1803 FILTER=nil means clear only images that haven't been
1804 displayed for some time.
1805 Else, only free the images which have FILTER in their `dependencies'.
1806 Should be called from time to time to reduce the number of loaded images.
1807 If image-cache-eviction-delay is non-nil, this frees images in the cache
1808 which weren't displayed for at least that many seconds. */
1810 void
1811 clear_image_cache (struct frame *f, Lisp_Object filter)
1813 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1815 if (c && (!NILP (filter) || INTEGERP (Vimage_cache_eviction_delay)))
1817 EMACS_TIME t;
1818 unsigned long old;
1819 int i, nfreed;
1821 EMACS_GET_TIME (t);
1822 old = EMACS_SECS (t) - XFASTINT (Vimage_cache_eviction_delay);
1824 /* Block input so that we won't be interrupted by a SIGIO
1825 while being in an inconsistent state. */
1826 BLOCK_INPUT;
1828 for (i = nfreed = 0; i < c->used; ++i)
1830 struct image *img = c->images[i];
1831 if (img != NULL
1832 && (NILP (filter) ? img->timestamp < old
1833 : (EQ (Qt, filter)
1834 || !NILP (Fmember (filter, img->dependencies)))))
1836 free_image (f, img);
1837 ++nfreed;
1841 /* We may be clearing the image cache because, for example,
1842 Emacs was iconified for a longer period of time. In that
1843 case, current matrices may still contain references to
1844 images freed above. So, clear these matrices. */
1845 if (nfreed)
1847 Lisp_Object tail, frame;
1849 FOR_EACH_FRAME (tail, frame)
1851 struct frame *f = XFRAME (frame);
1852 if (FRAME_IMAGE_CACHE (f) == c)
1853 clear_current_matrices (f);
1856 ++windows_or_buffers_changed;
1859 UNBLOCK_INPUT;
1863 void
1864 clear_image_caches (Lisp_Object filter)
1866 /* FIXME: We want to do
1867 * struct terminal *t;
1868 * for (t = terminal_list; t; t = t->next_terminal)
1869 * clear_image_cache (t, filter); */
1870 Lisp_Object tail, frame;
1871 FOR_EACH_FRAME (tail, frame)
1872 if (FRAME_WINDOW_P (XFRAME (frame)))
1873 clear_image_cache (XFRAME (frame), filter);
1876 DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache,
1877 0, 1, 0,
1878 doc: /* Clear the image cache.
1879 FILTER nil or a frame means clear all images in the selected frame.
1880 FILTER t means clear the image caches of all frames.
1881 Anything else, means only clear those images which refer to FILTER,
1882 which is then usually a filename. */)
1883 (filter)
1884 Lisp_Object filter;
1886 if (!(EQ (filter, Qnil) || FRAMEP (filter)))
1887 clear_image_caches (filter);
1888 else
1889 clear_image_cache (check_x_frame (filter), Qt);
1891 return Qnil;
1895 DEFUN ("image-refresh", Fimage_refresh, Simage_refresh,
1896 1, 2, 0,
1897 doc: /* Refresh the image with specification SPEC on frame FRAME.
1898 If SPEC specifies an image file, the displayed image is updated with
1899 the current contents of that file.
1900 FRAME nil or omitted means use the selected frame.
1901 FRAME t means refresh the image on all frames. */)
1902 (spec, frame)
1903 Lisp_Object spec, frame;
1905 if (!valid_image_p (spec))
1906 error ("Invalid image specification");
1908 if (EQ (frame, Qt))
1910 Lisp_Object tail;
1911 FOR_EACH_FRAME (tail, frame)
1913 struct frame *f = XFRAME (frame);
1914 if (FRAME_WINDOW_P (f))
1915 uncache_image (f, spec);
1918 else
1919 uncache_image (check_x_frame (frame), spec);
1921 return Qnil;
1925 /* Compute masks and transform image IMG on frame F, as specified
1926 by the image's specification, */
1928 static void
1929 postprocess_image (f, img)
1930 struct frame *f;
1931 struct image *img;
1933 /* Manipulation of the image's mask. */
1934 if (img->pixmap)
1936 Lisp_Object conversion, spec;
1937 Lisp_Object mask;
1939 spec = img->spec;
1941 /* `:heuristic-mask t'
1942 `:mask heuristic'
1943 means build a mask heuristically.
1944 `:heuristic-mask (R G B)'
1945 `:mask (heuristic (R G B))'
1946 means build a mask from color (R G B) in the
1947 image.
1948 `:mask nil'
1949 means remove a mask, if any. */
1951 mask = image_spec_value (spec, QCheuristic_mask, NULL);
1952 if (!NILP (mask))
1953 x_build_heuristic_mask (f, img, mask);
1954 else
1956 int found_p;
1958 mask = image_spec_value (spec, QCmask, &found_p);
1960 if (EQ (mask, Qheuristic))
1961 x_build_heuristic_mask (f, img, Qt);
1962 else if (CONSP (mask)
1963 && EQ (XCAR (mask), Qheuristic))
1965 if (CONSP (XCDR (mask)))
1966 x_build_heuristic_mask (f, img, XCAR (XCDR (mask)));
1967 else
1968 x_build_heuristic_mask (f, img, XCDR (mask));
1970 else if (NILP (mask) && found_p && img->mask)
1972 Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
1973 img->mask = NO_PIXMAP;
1978 /* Should we apply an image transformation algorithm? */
1979 conversion = image_spec_value (spec, QCconversion, NULL);
1980 if (EQ (conversion, Qdisabled))
1981 x_disable_image (f, img);
1982 else if (EQ (conversion, Qlaplace))
1983 x_laplace (f, img);
1984 else if (EQ (conversion, Qemboss))
1985 x_emboss (f, img);
1986 else if (CONSP (conversion)
1987 && EQ (XCAR (conversion), Qedge_detection))
1989 Lisp_Object tem;
1990 tem = XCDR (conversion);
1991 if (CONSP (tem))
1992 x_edge_detection (f, img,
1993 Fplist_get (tem, QCmatrix),
1994 Fplist_get (tem, QCcolor_adjustment));
2000 /* Return the id of image with Lisp specification SPEC on frame F.
2001 SPEC must be a valid Lisp image specification (see valid_image_p). */
2004 lookup_image (f, spec)
2005 struct frame *f;
2006 Lisp_Object spec;
2008 struct image_cache *c;
2009 struct image *img;
2010 unsigned hash;
2011 struct gcpro gcpro1;
2012 EMACS_TIME now;
2014 /* F must be a window-system frame, and SPEC must be a valid image
2015 specification. */
2016 xassert (FRAME_WINDOW_P (f));
2017 xassert (valid_image_p (spec));
2019 c = FRAME_IMAGE_CACHE (f);
2021 GCPRO1 (spec);
2023 /* Look up SPEC in the hash table of the image cache. */
2024 hash = sxhash (spec, 0);
2025 img = search_image_cache (f, spec, hash);
2026 if (img && img->load_failed_p)
2028 free_image (f, img);
2029 img = NULL;
2032 /* If not found, create a new image and cache it. */
2033 if (img == NULL)
2035 extern Lisp_Object Qpostscript;
2037 BLOCK_INPUT;
2038 img = make_image (spec, hash);
2039 cache_image (f, img);
2040 img->load_failed_p = img->type->load (f, img) == 0;
2041 img->frame_foreground = FRAME_FOREGROUND_PIXEL (f);
2042 img->frame_background = FRAME_BACKGROUND_PIXEL (f);
2044 /* If we can't load the image, and we don't have a width and
2045 height, use some arbitrary width and height so that we can
2046 draw a rectangle for it. */
2047 if (img->load_failed_p)
2049 Lisp_Object value;
2051 value = image_spec_value (spec, QCwidth, NULL);
2052 img->width = (INTEGERP (value)
2053 ? XFASTINT (value) : DEFAULT_IMAGE_WIDTH);
2054 value = image_spec_value (spec, QCheight, NULL);
2055 img->height = (INTEGERP (value)
2056 ? XFASTINT (value) : DEFAULT_IMAGE_HEIGHT);
2058 else
2060 /* Handle image type independent image attributes
2061 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
2062 `:background COLOR'. */
2063 Lisp_Object ascent, margin, relief, bg;
2065 ascent = image_spec_value (spec, QCascent, NULL);
2066 if (INTEGERP (ascent))
2067 img->ascent = XFASTINT (ascent);
2068 else if (EQ (ascent, Qcenter))
2069 img->ascent = CENTERED_IMAGE_ASCENT;
2071 margin = image_spec_value (spec, QCmargin, NULL);
2072 if (INTEGERP (margin) && XINT (margin) >= 0)
2073 img->vmargin = img->hmargin = XFASTINT (margin);
2074 else if (CONSP (margin) && INTEGERP (XCAR (margin))
2075 && INTEGERP (XCDR (margin)))
2077 if (XINT (XCAR (margin)) > 0)
2078 img->hmargin = XFASTINT (XCAR (margin));
2079 if (XINT (XCDR (margin)) > 0)
2080 img->vmargin = XFASTINT (XCDR (margin));
2083 relief = image_spec_value (spec, QCrelief, NULL);
2084 if (INTEGERP (relief))
2086 img->relief = XINT (relief);
2087 img->hmargin += eabs (img->relief);
2088 img->vmargin += eabs (img->relief);
2091 if (! img->background_valid)
2093 bg = image_spec_value (img->spec, QCbackground, NULL);
2094 if (!NILP (bg))
2096 img->background
2097 = x_alloc_image_color (f, img, bg,
2098 FRAME_BACKGROUND_PIXEL (f));
2099 img->background_valid = 1;
2103 /* Do image transformations and compute masks, unless we
2104 don't have the image yet. */
2105 if (!EQ (*img->type->type, Qpostscript))
2106 postprocess_image (f, img);
2109 UNBLOCK_INPUT;
2112 /* We're using IMG, so set its timestamp to `now'. */
2113 EMACS_GET_TIME (now);
2114 img->timestamp = EMACS_SECS (now);
2116 UNGCPRO;
2118 /* Value is the image id. */
2119 return img->id;
2123 /* Cache image IMG in the image cache of frame F. */
2125 static void
2126 cache_image (f, img)
2127 struct frame *f;
2128 struct image *img;
2130 struct image_cache *c = FRAME_IMAGE_CACHE (f);
2131 int i;
2133 /* Find a free slot in c->images. */
2134 for (i = 0; i < c->used; ++i)
2135 if (c->images[i] == NULL)
2136 break;
2138 /* If no free slot found, maybe enlarge c->images. */
2139 if (i == c->used && c->used == c->size)
2141 c->size *= 2;
2142 c->images = (struct image **) xrealloc (c->images,
2143 c->size * sizeof *c->images);
2146 /* Add IMG to c->images, and assign IMG an id. */
2147 c->images[i] = img;
2148 img->id = i;
2149 if (i == c->used)
2150 ++c->used;
2152 /* Add IMG to the cache's hash table. */
2153 i = img->hash % IMAGE_CACHE_BUCKETS_SIZE;
2154 img->next = c->buckets[i];
2155 if (img->next)
2156 img->next->prev = img;
2157 img->prev = NULL;
2158 c->buckets[i] = img;
2162 /* Call FN on every image in the image cache of frame F. Used to mark
2163 Lisp Objects in the image cache. */
2165 /* Mark Lisp objects in image IMG. */
2167 static void
2168 mark_image (img)
2169 struct image *img;
2171 mark_object (img->spec);
2172 mark_object (img->dependencies);
2174 if (!NILP (img->data.lisp_val))
2175 mark_object (img->data.lisp_val);
2179 void
2180 mark_image_cache (struct image_cache *c)
2182 if (c)
2184 int i;
2185 for (i = 0; i < c->used; ++i)
2186 if (c->images[i])
2187 mark_image (c->images[i]);
2193 /***********************************************************************
2194 X / NS / W32 support code
2195 ***********************************************************************/
2197 #ifdef HAVE_NTGUI
2199 /* Macro for defining functions that will be loaded from image DLLs. */
2200 #define DEF_IMGLIB_FN(func) int (FAR CDECL *fn_##func)()
2202 /* Macro for loading those image functions from the library. */
2203 #define LOAD_IMGLIB_FN(lib,func) { \
2204 fn_##func = (void *) GetProcAddress (lib, #func); \
2205 if (!fn_##func) return 0; \
2208 /* Load a DLL implementing an image type.
2209 The `image-library-alist' variable associates a symbol,
2210 identifying an image type, to a list of possible filenames.
2211 The function returns NULL if no library could be loaded for
2212 the given image type, or if the library was previously loaded;
2213 else the handle of the DLL. */
2214 static HMODULE
2215 w32_delayed_load (Lisp_Object libraries, Lisp_Object type)
2217 HMODULE library = NULL;
2219 if (CONSP (libraries) && NILP (Fassq (type, Vimage_type_cache)))
2221 Lisp_Object dlls = Fassq (type, libraries);
2223 if (CONSP (dlls))
2224 for (dlls = XCDR (dlls); CONSP (dlls); dlls = XCDR (dlls))
2226 CHECK_STRING_CAR (dlls);
2227 if (library = LoadLibrary (SDATA (XCAR (dlls))))
2228 break;
2232 return library;
2235 #endif /* HAVE_NTGUI */
2237 static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int,
2238 XImagePtr *, Pixmap *));
2239 static void x_destroy_x_image P_ ((XImagePtr));
2240 static void x_put_x_image P_ ((struct frame *, XImagePtr, Pixmap, int, int));
2243 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
2244 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
2245 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
2246 via xmalloc. Print error messages via image_error if an error
2247 occurs. Value is non-zero if successful.
2249 On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
2250 should indicate the bit depth of the image. */
2252 static int
2253 x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap)
2254 struct frame *f;
2255 int width, height, depth;
2256 XImagePtr *ximg;
2257 Pixmap *pixmap;
2259 #ifdef HAVE_X_WINDOWS
2260 Display *display = FRAME_X_DISPLAY (f);
2261 Window window = FRAME_X_WINDOW (f);
2262 Screen *screen = FRAME_X_SCREEN (f);
2264 xassert (interrupt_input_blocked);
2266 if (depth <= 0)
2267 depth = DefaultDepthOfScreen (screen);
2268 *ximg = XCreateImage (display, DefaultVisualOfScreen (screen),
2269 depth, ZPixmap, 0, NULL, width, height,
2270 depth > 16 ? 32 : depth > 8 ? 16 : 8, 0);
2271 if (*ximg == NULL)
2273 image_error ("Unable to allocate X image", Qnil, Qnil);
2274 return 0;
2277 /* Allocate image raster. */
2278 (*ximg)->data = (char *) xmalloc ((*ximg)->bytes_per_line * height);
2280 /* Allocate a pixmap of the same size. */
2281 *pixmap = XCreatePixmap (display, window, width, height, depth);
2282 if (*pixmap == NO_PIXMAP)
2284 x_destroy_x_image (*ximg);
2285 *ximg = NULL;
2286 image_error ("Unable to create X pixmap", Qnil, Qnil);
2287 return 0;
2290 return 1;
2291 #endif /* HAVE_X_WINDOWS */
2293 #ifdef HAVE_NTGUI
2295 BITMAPINFOHEADER *header;
2296 HDC hdc;
2297 int scanline_width_bits;
2298 int remainder;
2299 int palette_colors = 0;
2301 if (depth == 0)
2302 depth = 24;
2304 if (depth != 1 && depth != 4 && depth != 8
2305 && depth != 16 && depth != 24 && depth != 32)
2307 image_error ("Invalid image bit depth specified", Qnil, Qnil);
2308 return 0;
2311 scanline_width_bits = width * depth;
2312 remainder = scanline_width_bits % 32;
2314 if (remainder)
2315 scanline_width_bits += 32 - remainder;
2317 /* Bitmaps with a depth less than 16 need a palette. */
2318 /* BITMAPINFO structure already contains the first RGBQUAD. */
2319 if (depth < 16)
2320 palette_colors = 1 << depth - 1;
2322 *ximg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD));
2323 if (*ximg == NULL)
2325 image_error ("Unable to allocate memory for XImage", Qnil, Qnil);
2326 return 0;
2329 header = &((*ximg)->info.bmiHeader);
2330 bzero (&((*ximg)->info), sizeof (BITMAPINFO));
2331 header->biSize = sizeof (*header);
2332 header->biWidth = width;
2333 header->biHeight = -height; /* negative indicates a top-down bitmap. */
2334 header->biPlanes = 1;
2335 header->biBitCount = depth;
2336 header->biCompression = BI_RGB;
2337 header->biClrUsed = palette_colors;
2339 /* TODO: fill in palette. */
2340 if (depth == 1)
2342 (*ximg)->info.bmiColors[0].rgbBlue = 0;
2343 (*ximg)->info.bmiColors[0].rgbGreen = 0;
2344 (*ximg)->info.bmiColors[0].rgbRed = 0;
2345 (*ximg)->info.bmiColors[0].rgbReserved = 0;
2346 (*ximg)->info.bmiColors[1].rgbBlue = 255;
2347 (*ximg)->info.bmiColors[1].rgbGreen = 255;
2348 (*ximg)->info.bmiColors[1].rgbRed = 255;
2349 (*ximg)->info.bmiColors[1].rgbReserved = 0;
2352 hdc = get_frame_dc (f);
2354 /* Create a DIBSection and raster array for the bitmap,
2355 and store its handle in *pixmap. */
2356 *pixmap = CreateDIBSection (hdc, &((*ximg)->info),
2357 (depth < 16) ? DIB_PAL_COLORS : DIB_RGB_COLORS,
2358 /* casting avoids a GCC warning */
2359 (void **)&((*ximg)->data), NULL, 0);
2361 /* Realize display palette and garbage all frames. */
2362 release_frame_dc (f, hdc);
2364 if (*pixmap == NULL)
2366 DWORD err = GetLastError ();
2367 Lisp_Object errcode;
2368 /* All system errors are < 10000, so the following is safe. */
2369 XSETINT (errcode, (int) err);
2370 image_error ("Unable to create bitmap, error code %d", errcode, Qnil);
2371 x_destroy_x_image (*ximg);
2372 return 0;
2375 return 1;
2377 #endif /* HAVE_NTGUI */
2379 #ifdef HAVE_NS
2380 *pixmap = ns_image_for_XPM(width, height, depth);
2381 if (*pixmap == 0)
2383 *ximg = NULL;
2384 image_error ("Unable to allocate NSImage for XPM pixmap", Qnil, Qnil);
2385 return 0;
2387 *ximg = *pixmap;
2388 return 1;
2389 #endif
2393 /* Destroy XImage XIMG. Free XIMG->data. */
2395 static void
2396 x_destroy_x_image (ximg)
2397 XImagePtr ximg;
2399 xassert (interrupt_input_blocked);
2400 if (ximg)
2402 #ifdef HAVE_X_WINDOWS
2403 xfree (ximg->data);
2404 ximg->data = NULL;
2405 XDestroyImage (ximg);
2406 #endif /* HAVE_X_WINDOWS */
2407 #ifdef HAVE_NTGUI
2408 /* Data will be freed by DestroyObject. */
2409 ximg->data = NULL;
2410 xfree (ximg);
2411 #endif /* HAVE_NTGUI */
2412 #ifdef HAVE_NS
2413 ns_release_object(ximg);
2414 #endif /* HAVE_NS */
2419 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
2420 are width and height of both the image and pixmap. */
2422 static void
2423 x_put_x_image (f, ximg, pixmap, width, height)
2424 struct frame *f;
2425 XImagePtr ximg;
2426 Pixmap pixmap;
2427 int width, height;
2429 #ifdef HAVE_X_WINDOWS
2430 GC gc;
2432 xassert (interrupt_input_blocked);
2433 gc = XCreateGC (FRAME_X_DISPLAY (f), pixmap, 0, NULL);
2434 XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, ximg, 0, 0, 0, 0, width, height);
2435 XFreeGC (FRAME_X_DISPLAY (f), gc);
2436 #endif /* HAVE_X_WINDOWS */
2438 #ifdef HAVE_NTGUI
2439 #if 0 /* I don't think this is necessary looking at where it is used. */
2440 HDC hdc = get_frame_dc (f);
2441 SetDIBits (hdc, pixmap, 0, height, ximg->data, &(ximg->info), DIB_RGB_COLORS);
2442 release_frame_dc (f, hdc);
2443 #endif
2444 #endif /* HAVE_NTGUI */
2446 #ifdef HAVE_NS
2447 xassert (ximg == pixmap);
2448 ns_retain_object(ximg);
2449 #endif
2453 /***********************************************************************
2454 File Handling
2455 ***********************************************************************/
2457 static unsigned char *slurp_file P_ ((char *, int *));
2460 /* Find image file FILE. Look in data-directory/images, then
2461 x-bitmap-file-path. Value is the encoded full name of the file
2462 found, or nil if not found. */
2464 Lisp_Object
2465 x_find_image_file (file)
2466 Lisp_Object file;
2468 Lisp_Object file_found, search_path;
2469 struct gcpro gcpro1, gcpro2;
2470 int fd;
2472 file_found = Qnil;
2473 /* TODO I think this should use something like image-load-path
2474 instead. Unfortunately, that can contain non-string elements. */
2475 search_path = Fcons (Fexpand_file_name (build_string ("images"),
2476 Vdata_directory),
2477 Vx_bitmap_file_path);
2478 GCPRO2 (file_found, search_path);
2480 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
2481 fd = openp (search_path, file, Qnil, &file_found, Qnil);
2483 if (fd == -1)
2484 file_found = Qnil;
2485 else
2487 file_found = ENCODE_FILE (file_found);
2488 close (fd);
2491 UNGCPRO;
2492 return file_found;
2496 /* Read FILE into memory. Value is a pointer to a buffer allocated
2497 with xmalloc holding FILE's contents. Value is null if an error
2498 occurred. *SIZE is set to the size of the file. */
2500 static unsigned char *
2501 slurp_file (file, size)
2502 char *file;
2503 int *size;
2505 FILE *fp = NULL;
2506 unsigned char *buf = NULL;
2507 struct stat st;
2509 if (stat (file, &st) == 0
2510 && (fp = fopen (file, "rb")) != NULL
2511 && (buf = (unsigned char *) xmalloc (st.st_size),
2512 fread (buf, 1, st.st_size, fp) == st.st_size))
2514 *size = st.st_size;
2515 fclose (fp);
2517 else
2519 if (fp)
2520 fclose (fp);
2521 if (buf)
2523 xfree (buf);
2524 buf = NULL;
2528 return buf;
2533 /***********************************************************************
2534 XBM images
2535 ***********************************************************************/
2537 static int xbm_scan P_ ((unsigned char **, unsigned char *, char *, int *));
2538 static int xbm_load P_ ((struct frame *f, struct image *img));
2539 static int xbm_load_image P_ ((struct frame *f, struct image *img,
2540 unsigned char *, unsigned char *));
2541 static int xbm_image_p P_ ((Lisp_Object object));
2542 static int xbm_read_bitmap_data P_ ((struct frame *f,
2543 unsigned char *, unsigned char *,
2544 int *, int *, unsigned char **));
2545 static int xbm_file_p P_ ((Lisp_Object));
2548 /* Indices of image specification fields in xbm_format, below. */
2550 enum xbm_keyword_index
2552 XBM_TYPE,
2553 XBM_FILE,
2554 XBM_WIDTH,
2555 XBM_HEIGHT,
2556 XBM_DATA,
2557 XBM_FOREGROUND,
2558 XBM_BACKGROUND,
2559 XBM_ASCENT,
2560 XBM_MARGIN,
2561 XBM_RELIEF,
2562 XBM_ALGORITHM,
2563 XBM_HEURISTIC_MASK,
2564 XBM_MASK,
2565 XBM_LAST
2568 /* Vector of image_keyword structures describing the format
2569 of valid XBM image specifications. */
2571 static struct image_keyword xbm_format[XBM_LAST] =
2573 {":type", IMAGE_SYMBOL_VALUE, 1},
2574 {":file", IMAGE_STRING_VALUE, 0},
2575 {":width", IMAGE_POSITIVE_INTEGER_VALUE, 0},
2576 {":height", IMAGE_POSITIVE_INTEGER_VALUE, 0},
2577 {":data", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
2578 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
2579 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
2580 {":ascent", IMAGE_ASCENT_VALUE, 0},
2581 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
2582 {":relief", IMAGE_INTEGER_VALUE, 0},
2583 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
2584 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
2585 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
2588 /* Structure describing the image type XBM. */
2590 static struct image_type xbm_type =
2592 &Qxbm,
2593 xbm_image_p,
2594 xbm_load,
2595 x_clear_image,
2596 NULL
2599 /* Tokens returned from xbm_scan. */
2601 enum xbm_token
2603 XBM_TK_IDENT = 256,
2604 XBM_TK_NUMBER
2608 /* Return non-zero if OBJECT is a valid XBM-type image specification.
2609 A valid specification is a list starting with the symbol `image'
2610 The rest of the list is a property list which must contain an
2611 entry `:type xbm..
2613 If the specification specifies a file to load, it must contain
2614 an entry `:file FILENAME' where FILENAME is a string.
2616 If the specification is for a bitmap loaded from memory it must
2617 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
2618 WIDTH and HEIGHT are integers > 0. DATA may be:
2620 1. a string large enough to hold the bitmap data, i.e. it must
2621 have a size >= (WIDTH + 7) / 8 * HEIGHT
2623 2. a bool-vector of size >= WIDTH * HEIGHT
2625 3. a vector of strings or bool-vectors, one for each line of the
2626 bitmap.
2628 4. a string containing an in-memory XBM file. WIDTH and HEIGHT
2629 may not be specified in this case because they are defined in the
2630 XBM file.
2632 Both the file and data forms may contain the additional entries
2633 `:background COLOR' and `:foreground COLOR'. If not present,
2634 foreground and background of the frame on which the image is
2635 displayed is used. */
2637 static int
2638 xbm_image_p (object)
2639 Lisp_Object object;
2641 struct image_keyword kw[XBM_LAST];
2643 bcopy (xbm_format, kw, sizeof kw);
2644 if (!parse_image_spec (object, kw, XBM_LAST, Qxbm))
2645 return 0;
2647 xassert (EQ (kw[XBM_TYPE].value, Qxbm));
2649 if (kw[XBM_FILE].count)
2651 if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_DATA].count)
2652 return 0;
2654 else if (kw[XBM_DATA].count && xbm_file_p (kw[XBM_DATA].value))
2656 /* In-memory XBM file. */
2657 if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_FILE].count)
2658 return 0;
2660 else
2662 Lisp_Object data;
2663 int width, height;
2665 /* Entries for `:width', `:height' and `:data' must be present. */
2666 if (!kw[XBM_WIDTH].count
2667 || !kw[XBM_HEIGHT].count
2668 || !kw[XBM_DATA].count)
2669 return 0;
2671 data = kw[XBM_DATA].value;
2672 width = XFASTINT (kw[XBM_WIDTH].value);
2673 height = XFASTINT (kw[XBM_HEIGHT].value);
2675 /* Check type of data, and width and height against contents of
2676 data. */
2677 if (VECTORP (data))
2679 int i;
2681 /* Number of elements of the vector must be >= height. */
2682 if (XVECTOR (data)->size < height)
2683 return 0;
2685 /* Each string or bool-vector in data must be large enough
2686 for one line of the image. */
2687 for (i = 0; i < height; ++i)
2689 Lisp_Object elt = XVECTOR (data)->contents[i];
2691 if (STRINGP (elt))
2693 if (SCHARS (elt)
2694 < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR)
2695 return 0;
2697 else if (BOOL_VECTOR_P (elt))
2699 if (XBOOL_VECTOR (elt)->size < width)
2700 return 0;
2702 else
2703 return 0;
2706 else if (STRINGP (data))
2708 if (SCHARS (data)
2709 < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR * height)
2710 return 0;
2712 else if (BOOL_VECTOR_P (data))
2714 if (XBOOL_VECTOR (data)->size < width * height)
2715 return 0;
2717 else
2718 return 0;
2721 return 1;
2725 /* Scan a bitmap file. FP is the stream to read from. Value is
2726 either an enumerator from enum xbm_token, or a character for a
2727 single-character token, or 0 at end of file. If scanning an
2728 identifier, store the lexeme of the identifier in SVAL. If
2729 scanning a number, store its value in *IVAL. */
2731 static int
2732 xbm_scan (s, end, sval, ival)
2733 unsigned char **s, *end;
2734 char *sval;
2735 int *ival;
2737 unsigned int c;
2739 loop:
2741 /* Skip white space. */
2742 while (*s < end && (c = *(*s)++, isspace (c)))
2745 if (*s >= end)
2746 c = 0;
2747 else if (isdigit (c))
2749 int value = 0, digit;
2751 if (c == '0' && *s < end)
2753 c = *(*s)++;
2754 if (c == 'x' || c == 'X')
2756 while (*s < end)
2758 c = *(*s)++;
2759 if (isdigit (c))
2760 digit = c - '0';
2761 else if (c >= 'a' && c <= 'f')
2762 digit = c - 'a' + 10;
2763 else if (c >= 'A' && c <= 'F')
2764 digit = c - 'A' + 10;
2765 else
2766 break;
2767 value = 16 * value + digit;
2770 else if (isdigit (c))
2772 value = c - '0';
2773 while (*s < end
2774 && (c = *(*s)++, isdigit (c)))
2775 value = 8 * value + c - '0';
2778 else
2780 value = c - '0';
2781 while (*s < end
2782 && (c = *(*s)++, isdigit (c)))
2783 value = 10 * value + c - '0';
2786 if (*s < end)
2787 *s = *s - 1;
2788 *ival = value;
2789 c = XBM_TK_NUMBER;
2791 else if (isalpha (c) || c == '_')
2793 *sval++ = c;
2794 while (*s < end
2795 && (c = *(*s)++, (isalnum (c) || c == '_')))
2796 *sval++ = c;
2797 *sval = 0;
2798 if (*s < end)
2799 *s = *s - 1;
2800 c = XBM_TK_IDENT;
2802 else if (c == '/' && **s == '*')
2804 /* C-style comment. */
2805 ++*s;
2806 while (**s && (**s != '*' || *(*s + 1) != '/'))
2807 ++*s;
2808 if (**s)
2810 *s += 2;
2811 goto loop;
2815 return c;
2818 #ifdef HAVE_NTGUI
2820 /* Create a Windows bitmap from X bitmap data. */
2821 static HBITMAP
2822 w32_create_pixmap_from_bitmap_data (int width, int height, char *data)
2824 static unsigned char swap_nibble[16]
2825 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
2826 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
2827 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
2828 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
2829 int i, j, w1, w2;
2830 unsigned char *bits, *p;
2831 HBITMAP bmp;
2833 w1 = (width + 7) / 8; /* nb of 8bits elt in X bitmap */
2834 w2 = ((width + 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
2835 bits = (unsigned char *) alloca (height * w2);
2836 bzero (bits, height * w2);
2837 for (i = 0; i < height; i++)
2839 p = bits + i*w2;
2840 for (j = 0; j < w1; j++)
2842 /* Bitswap XBM bytes to match how Windows does things. */
2843 unsigned char c = *data++;
2844 *p++ = (unsigned char)((swap_nibble[c & 0xf] << 4)
2845 | (swap_nibble[(c>>4) & 0xf]));
2848 bmp = CreateBitmap (width, height, 1, 1, (char *) bits);
2850 return bmp;
2853 static void
2854 convert_mono_to_color_image (f, img, foreground, background)
2855 struct frame *f;
2856 struct image *img;
2857 COLORREF foreground, background;
2859 HDC hdc, old_img_dc, new_img_dc;
2860 HGDIOBJ old_prev, new_prev;
2861 HBITMAP new_pixmap;
2863 hdc = get_frame_dc (f);
2864 old_img_dc = CreateCompatibleDC (hdc);
2865 new_img_dc = CreateCompatibleDC (hdc);
2866 new_pixmap = CreateCompatibleBitmap (hdc, img->width, img->height);
2867 release_frame_dc (f, hdc);
2868 old_prev = SelectObject (old_img_dc, img->pixmap);
2869 new_prev = SelectObject (new_img_dc, new_pixmap);
2870 /* Windows convention for mono bitmaps is black = background,
2871 white = foreground. */
2872 SetTextColor (new_img_dc, background);
2873 SetBkColor (new_img_dc, foreground);
2875 BitBlt (new_img_dc, 0, 0, img->width, img->height, old_img_dc,
2876 0, 0, SRCCOPY);
2878 SelectObject (old_img_dc, old_prev);
2879 SelectObject (new_img_dc, new_prev);
2880 DeleteDC (old_img_dc);
2881 DeleteDC (new_img_dc);
2882 DeleteObject (img->pixmap);
2883 if (new_pixmap == 0)
2884 fprintf (stderr, "Failed to convert image to color.\n");
2885 else
2886 img->pixmap = new_pixmap;
2889 #define XBM_BIT_SHUFFLE(b) (~(b))
2891 #else
2893 #define XBM_BIT_SHUFFLE(b) (b)
2895 #endif /* HAVE_NTGUI */
2898 static void
2899 Create_Pixmap_From_Bitmap_Data (f, img, data, fg, bg, non_default_colors)
2900 struct frame *f;
2901 struct image *img;
2902 char *data;
2903 RGB_PIXEL_COLOR fg, bg;
2904 int non_default_colors;
2906 #ifdef HAVE_NTGUI
2907 img->pixmap
2908 = w32_create_pixmap_from_bitmap_data (img->width, img->height, data);
2910 /* If colors were specified, transfer the bitmap to a color one. */
2911 if (non_default_colors)
2912 convert_mono_to_color_image (f, img, fg, bg);
2914 #elif defined (HAVE_NS)
2915 img->pixmap = ns_image_from_XBM(data, img->width, img->height);
2917 #else
2918 img->pixmap
2919 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
2920 FRAME_X_WINDOW (f),
2921 data,
2922 img->width, img->height,
2923 fg, bg,
2924 DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
2925 #endif /* !HAVE_NTGUI && !HAVE_NS */
2930 /* Replacement for XReadBitmapFileData which isn't available under old
2931 X versions. CONTENTS is a pointer to a buffer to parse; END is the
2932 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
2933 the image. Return in *DATA the bitmap data allocated with xmalloc.
2934 Value is non-zero if successful. DATA null means just test if
2935 CONTENTS looks like an in-memory XBM file. */
2937 static int
2938 xbm_read_bitmap_data (f, contents, end, width, height, data)
2939 struct frame *f;
2940 unsigned char *contents, *end;
2941 int *width, *height;
2942 unsigned char **data;
2944 unsigned char *s = contents;
2945 char buffer[BUFSIZ];
2946 int padding_p = 0;
2947 int v10 = 0;
2948 int bytes_per_line, i, nbytes;
2949 unsigned char *p;
2950 int value;
2951 int LA1;
2953 #define match() \
2954 LA1 = xbm_scan (&s, end, buffer, &value)
2956 #define expect(TOKEN) \
2957 if (LA1 != (TOKEN)) \
2958 goto failure; \
2959 else \
2960 match ()
2962 #define expect_ident(IDENT) \
2963 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
2964 match (); \
2965 else \
2966 goto failure
2968 *width = *height = -1;
2969 if (data)
2970 *data = NULL;
2971 LA1 = xbm_scan (&s, end, buffer, &value);
2973 /* Parse defines for width, height and hot-spots. */
2974 while (LA1 == '#')
2976 match ();
2977 expect_ident ("define");
2978 expect (XBM_TK_IDENT);
2980 if (LA1 == XBM_TK_NUMBER)
2982 char *p = strrchr (buffer, '_');
2983 p = p ? p + 1 : buffer;
2984 if (strcmp (p, "width") == 0)
2985 *width = value;
2986 else if (strcmp (p, "height") == 0)
2987 *height = value;
2989 expect (XBM_TK_NUMBER);
2992 if (!check_image_size (f, *width, *height))
2993 goto failure;
2994 else if (data == NULL)
2995 goto success;
2997 /* Parse bits. Must start with `static'. */
2998 expect_ident ("static");
2999 if (LA1 == XBM_TK_IDENT)
3001 if (strcmp (buffer, "unsigned") == 0)
3003 match ();
3004 expect_ident ("char");
3006 else if (strcmp (buffer, "short") == 0)
3008 match ();
3009 v10 = 1;
3010 if (*width % 16 && *width % 16 < 9)
3011 padding_p = 1;
3013 else if (strcmp (buffer, "char") == 0)
3014 match ();
3015 else
3016 goto failure;
3018 else
3019 goto failure;
3021 expect (XBM_TK_IDENT);
3022 expect ('[');
3023 expect (']');
3024 expect ('=');
3025 expect ('{');
3027 bytes_per_line = (*width + 7) / 8 + padding_p;
3028 nbytes = bytes_per_line * *height;
3029 p = *data = (unsigned char *) xmalloc (nbytes);
3031 if (v10)
3033 for (i = 0; i < nbytes; i += 2)
3035 int val = value;
3036 expect (XBM_TK_NUMBER);
3038 *p++ = XBM_BIT_SHUFFLE (val);
3039 if (!padding_p || ((i + 2) % bytes_per_line))
3040 *p++ = XBM_BIT_SHUFFLE (value >> 8);
3042 if (LA1 == ',' || LA1 == '}')
3043 match ();
3044 else
3045 goto failure;
3048 else
3050 for (i = 0; i < nbytes; ++i)
3052 int val = value;
3053 expect (XBM_TK_NUMBER);
3055 *p++ = XBM_BIT_SHUFFLE (val);
3057 if (LA1 == ',' || LA1 == '}')
3058 match ();
3059 else
3060 goto failure;
3064 success:
3065 return 1;
3067 failure:
3069 if (data && *data)
3071 xfree (*data);
3072 *data = NULL;
3074 return 0;
3076 #undef match
3077 #undef expect
3078 #undef expect_ident
3082 /* Load XBM image IMG which will be displayed on frame F from buffer
3083 CONTENTS. END is the end of the buffer. Value is non-zero if
3084 successful. */
3086 static int
3087 xbm_load_image (f, img, contents, end)
3088 struct frame *f;
3089 struct image *img;
3090 unsigned char *contents, *end;
3092 int rc;
3093 unsigned char *data;
3094 int success_p = 0;
3096 rc = xbm_read_bitmap_data (f, contents, end, &img->width, &img->height, &data);
3097 if (rc)
3099 unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
3100 unsigned long background = FRAME_BACKGROUND_PIXEL (f);
3101 int non_default_colors = 0;
3102 Lisp_Object value;
3104 xassert (img->width > 0 && img->height > 0);
3106 /* Get foreground and background colors, maybe allocate colors. */
3107 value = image_spec_value (img->spec, QCforeground, NULL);
3108 if (!NILP (value))
3110 foreground = x_alloc_image_color (f, img, value, foreground);
3111 non_default_colors = 1;
3113 value = image_spec_value (img->spec, QCbackground, NULL);
3114 if (!NILP (value))
3116 background = x_alloc_image_color (f, img, value, background);
3117 img->background = background;
3118 img->background_valid = 1;
3119 non_default_colors = 1;
3122 Create_Pixmap_From_Bitmap_Data (f, img, data,
3123 foreground, background,
3124 non_default_colors);
3125 xfree (data);
3127 if (img->pixmap == NO_PIXMAP)
3129 x_clear_image (f, img);
3130 image_error ("Unable to create X pixmap for `%s'", img->spec, Qnil);
3132 else
3133 success_p = 1;
3135 else
3136 image_error ("Error loading XBM image `%s'", img->spec, Qnil);
3138 return success_p;
3142 /* Value is non-zero if DATA looks like an in-memory XBM file. */
3144 static int
3145 xbm_file_p (data)
3146 Lisp_Object data;
3148 int w, h;
3149 return (STRINGP (data)
3150 && xbm_read_bitmap_data (NULL, SDATA (data),
3151 (SDATA (data)
3152 + SBYTES (data)),
3153 &w, &h, NULL));
3157 /* Fill image IMG which is used on frame F with pixmap data. Value is
3158 non-zero if successful. */
3160 static int
3161 xbm_load (f, img)
3162 struct frame *f;
3163 struct image *img;
3165 int success_p = 0;
3166 Lisp_Object file_name;
3168 xassert (xbm_image_p (img->spec));
3170 /* If IMG->spec specifies a file name, create a non-file spec from it. */
3171 file_name = image_spec_value (img->spec, QCfile, NULL);
3172 if (STRINGP (file_name))
3174 Lisp_Object file;
3175 unsigned char *contents;
3176 int size;
3177 struct gcpro gcpro1;
3179 file = x_find_image_file (file_name);
3180 GCPRO1 (file);
3181 if (!STRINGP (file))
3183 image_error ("Cannot find image file `%s'", file_name, Qnil);
3184 UNGCPRO;
3185 return 0;
3188 contents = slurp_file (SDATA (file), &size);
3189 if (contents == NULL)
3191 image_error ("Error loading XBM image `%s'", img->spec, Qnil);
3192 UNGCPRO;
3193 return 0;
3196 success_p = xbm_load_image (f, img, contents, contents + size);
3197 UNGCPRO;
3199 else
3201 struct image_keyword fmt[XBM_LAST];
3202 Lisp_Object data;
3203 unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
3204 unsigned long background = FRAME_BACKGROUND_PIXEL (f);
3205 int non_default_colors = 0;
3206 char *bits;
3207 int parsed_p;
3208 int in_memory_file_p = 0;
3210 /* See if data looks like an in-memory XBM file. */
3211 data = image_spec_value (img->spec, QCdata, NULL);
3212 in_memory_file_p = xbm_file_p (data);
3214 /* Parse the image specification. */
3215 bcopy (xbm_format, fmt, sizeof fmt);
3216 parsed_p = parse_image_spec (img->spec, fmt, XBM_LAST, Qxbm);
3217 xassert (parsed_p);
3219 /* Get specified width, and height. */
3220 if (!in_memory_file_p)
3222 img->width = XFASTINT (fmt[XBM_WIDTH].value);
3223 img->height = XFASTINT (fmt[XBM_HEIGHT].value);
3224 xassert (img->width > 0 && img->height > 0);
3227 /* Get foreground and background colors, maybe allocate colors. */
3228 if (fmt[XBM_FOREGROUND].count
3229 && STRINGP (fmt[XBM_FOREGROUND].value))
3231 foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value,
3232 foreground);
3233 non_default_colors = 1;
3236 if (fmt[XBM_BACKGROUND].count
3237 && STRINGP (fmt[XBM_BACKGROUND].value))
3239 background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value,
3240 background);
3241 non_default_colors = 1;
3244 if (in_memory_file_p)
3245 success_p = xbm_load_image (f, img, SDATA (data),
3246 (SDATA (data)
3247 + SBYTES (data)));
3248 else
3250 if (VECTORP (data))
3252 int i;
3253 char *p;
3254 int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
3256 p = bits = (char *) alloca (nbytes * img->height);
3257 for (i = 0; i < img->height; ++i, p += nbytes)
3259 Lisp_Object line = XVECTOR (data)->contents[i];
3260 if (STRINGP (line))
3261 bcopy (SDATA (line), p, nbytes);
3262 else
3263 bcopy (XBOOL_VECTOR (line)->data, p, nbytes);
3266 else if (STRINGP (data))
3267 bits = SDATA (data);
3268 else
3269 bits = XBOOL_VECTOR (data)->data;
3271 #ifdef WINDOWSNT
3273 char *invertedBits;
3274 int nbytes, i;
3275 /* Windows mono bitmaps are reversed compared with X. */
3276 invertedBits = bits;
3277 nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR
3278 * img->height;
3279 bits = (char *) alloca(nbytes);
3280 for (i = 0; i < nbytes; i++)
3281 bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]);
3283 #endif
3284 /* Create the pixmap. */
3286 Create_Pixmap_From_Bitmap_Data (f, img, bits,
3287 foreground, background,
3288 non_default_colors);
3289 if (img->pixmap)
3290 success_p = 1;
3291 else
3293 image_error ("Unable to create pixmap for XBM image `%s'",
3294 img->spec, Qnil);
3295 x_clear_image (f, img);
3300 return success_p;
3305 /***********************************************************************
3306 XPM images
3307 ***********************************************************************/
3309 #if defined (HAVE_XPM) || defined (HAVE_NS)
3311 static int xpm_image_p P_ ((Lisp_Object object));
3312 static int xpm_load P_ ((struct frame *f, struct image *img));
3313 static int xpm_valid_color_symbols_p P_ ((Lisp_Object));
3315 #endif /* HAVE_XPM || HAVE_NS */
3317 #ifdef HAVE_XPM
3318 #ifdef HAVE_NTGUI
3319 /* Indicate to xpm.h that we don't have Xlib. */
3320 #define FOR_MSW
3321 /* simx.h in xpm defines XColor and XImage differently than Emacs. */
3322 /* It also defines Display the same way as Emacs, but gcc 3.3 still barfs. */
3323 #define XColor xpm_XColor
3324 #define XImage xpm_XImage
3325 #define Display xpm_Display
3326 #define PIXEL_ALREADY_TYPEDEFED
3327 #include "X11/xpm.h"
3328 #undef FOR_MSW
3329 #undef XColor
3330 #undef XImage
3331 #undef Display
3332 #undef PIXEL_ALREADY_TYPEDEFED
3333 #else
3334 #include "X11/xpm.h"
3335 #endif /* HAVE_NTGUI */
3336 #endif /* HAVE_XPM */
3338 #if defined (HAVE_XPM) || defined (HAVE_NS)
3339 /* The symbol `xpm' identifying XPM-format images. */
3341 Lisp_Object Qxpm;
3343 /* Indices of image specification fields in xpm_format, below. */
3345 enum xpm_keyword_index
3347 XPM_TYPE,
3348 XPM_FILE,
3349 XPM_DATA,
3350 XPM_ASCENT,
3351 XPM_MARGIN,
3352 XPM_RELIEF,
3353 XPM_ALGORITHM,
3354 XPM_HEURISTIC_MASK,
3355 XPM_MASK,
3356 XPM_COLOR_SYMBOLS,
3357 XPM_BACKGROUND,
3358 XPM_LAST
3361 /* Vector of image_keyword structures describing the format
3362 of valid XPM image specifications. */
3364 static struct image_keyword xpm_format[XPM_LAST] =
3366 {":type", IMAGE_SYMBOL_VALUE, 1},
3367 {":file", IMAGE_STRING_VALUE, 0},
3368 {":data", IMAGE_STRING_VALUE, 0},
3369 {":ascent", IMAGE_ASCENT_VALUE, 0},
3370 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
3371 {":relief", IMAGE_INTEGER_VALUE, 0},
3372 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3373 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3374 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3375 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3376 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
3379 /* Structure describing the image type XPM. */
3381 static struct image_type xpm_type =
3383 &Qxpm,
3384 xpm_image_p,
3385 xpm_load,
3386 x_clear_image,
3387 NULL
3390 #ifdef HAVE_X_WINDOWS
3392 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
3393 functions for allocating image colors. Our own functions handle
3394 color allocation failures more gracefully than the ones on the XPM
3395 lib. */
3397 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
3398 #define ALLOC_XPM_COLORS
3399 #endif
3400 #endif /* HAVE_X_WINDOWS */
3402 #ifdef ALLOC_XPM_COLORS
3404 static void xpm_init_color_cache P_ ((struct frame *, XpmAttributes *));
3405 static void xpm_free_color_cache P_ ((void));
3406 static int xpm_lookup_color P_ ((struct frame *, char *, XColor *));
3407 static int xpm_color_bucket P_ ((char *));
3408 static struct xpm_cached_color *xpm_cache_color P_ ((struct frame *, char *,
3409 XColor *, int));
3411 /* An entry in a hash table used to cache color definitions of named
3412 colors. This cache is necessary to speed up XPM image loading in
3413 case we do color allocations ourselves. Without it, we would need
3414 a call to XParseColor per pixel in the image. */
3416 struct xpm_cached_color
3418 /* Next in collision chain. */
3419 struct xpm_cached_color *next;
3421 /* Color definition (RGB and pixel color). */
3422 XColor color;
3424 /* Color name. */
3425 char name[1];
3428 /* The hash table used for the color cache, and its bucket vector
3429 size. */
3431 #define XPM_COLOR_CACHE_BUCKETS 1001
3432 struct xpm_cached_color **xpm_color_cache;
3434 /* Initialize the color cache. */
3436 static void
3437 xpm_init_color_cache (f, attrs)
3438 struct frame *f;
3439 XpmAttributes *attrs;
3441 size_t nbytes = XPM_COLOR_CACHE_BUCKETS * sizeof *xpm_color_cache;
3442 xpm_color_cache = (struct xpm_cached_color **) xmalloc (nbytes);
3443 memset (xpm_color_cache, 0, nbytes);
3444 init_color_table ();
3446 if (attrs->valuemask & XpmColorSymbols)
3448 int i;
3449 XColor color;
3451 for (i = 0; i < attrs->numsymbols; ++i)
3452 if (XParseColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
3453 attrs->colorsymbols[i].value, &color))
3455 color.pixel = lookup_rgb_color (f, color.red, color.green,
3456 color.blue);
3457 xpm_cache_color (f, attrs->colorsymbols[i].name, &color, -1);
3462 /* Free the color cache. */
3464 static void
3465 xpm_free_color_cache ()
3467 struct xpm_cached_color *p, *next;
3468 int i;
3470 for (i = 0; i < XPM_COLOR_CACHE_BUCKETS; ++i)
3471 for (p = xpm_color_cache[i]; p; p = next)
3473 next = p->next;
3474 xfree (p);
3477 xfree (xpm_color_cache);
3478 xpm_color_cache = NULL;
3479 free_color_table ();
3482 /* Return the bucket index for color named COLOR_NAME in the color
3483 cache. */
3485 static int
3486 xpm_color_bucket (color_name)
3487 char *color_name;
3489 unsigned h = 0;
3490 char *s;
3492 for (s = color_name; *s; ++s)
3493 h = (h << 2) ^ *s;
3494 return h %= XPM_COLOR_CACHE_BUCKETS;
3498 /* On frame F, cache values COLOR for color with name COLOR_NAME.
3499 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
3500 entry added. */
3502 static struct xpm_cached_color *
3503 xpm_cache_color (f, color_name, color, bucket)
3504 struct frame *f;
3505 char *color_name;
3506 XColor *color;
3507 int bucket;
3509 size_t nbytes;
3510 struct xpm_cached_color *p;
3512 if (bucket < 0)
3513 bucket = xpm_color_bucket (color_name);
3515 nbytes = sizeof *p + strlen (color_name);
3516 p = (struct xpm_cached_color *) xmalloc (nbytes);
3517 strcpy (p->name, color_name);
3518 p->color = *color;
3519 p->next = xpm_color_cache[bucket];
3520 xpm_color_cache[bucket] = p;
3521 return p;
3524 /* Look up color COLOR_NAME for frame F in the color cache. If found,
3525 return the cached definition in *COLOR. Otherwise, make a new
3526 entry in the cache and allocate the color. Value is zero if color
3527 allocation failed. */
3529 static int
3530 xpm_lookup_color (f, color_name, color)
3531 struct frame *f;
3532 char *color_name;
3533 XColor *color;
3535 struct xpm_cached_color *p;
3536 int h = xpm_color_bucket (color_name);
3538 for (p = xpm_color_cache[h]; p; p = p->next)
3539 if (strcmp (p->name, color_name) == 0)
3540 break;
3542 if (p != NULL)
3543 *color = p->color;
3544 else if (XParseColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
3545 color_name, color))
3547 color->pixel = lookup_rgb_color (f, color->red, color->green,
3548 color->blue);
3549 p = xpm_cache_color (f, color_name, color, h);
3551 /* You get `opaque' at least from ImageMagick converting pbm to xpm
3552 with transparency, and it's useful. */
3553 else if (strcmp ("opaque", color_name) == 0)
3555 bzero (color, sizeof (XColor)); /* Is this necessary/correct? */
3556 color->pixel = FRAME_FOREGROUND_PIXEL (f);
3557 p = xpm_cache_color (f, color_name, color, h);
3560 return p != NULL;
3564 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
3565 CLOSURE is a pointer to the frame on which we allocate the
3566 color. Return in *COLOR the allocated color. Value is non-zero
3567 if successful. */
3569 static int
3570 xpm_alloc_color (dpy, cmap, color_name, color, closure)
3571 Display *dpy;
3572 Colormap cmap;
3573 char *color_name;
3574 XColor *color;
3575 void *closure;
3577 return xpm_lookup_color ((struct frame *) closure, color_name, color);
3581 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
3582 is a pointer to the frame on which we allocate the color. Value is
3583 non-zero if successful. */
3585 static int
3586 xpm_free_colors (dpy, cmap, pixels, npixels, closure)
3587 Display *dpy;
3588 Colormap cmap;
3589 Pixel *pixels;
3590 int npixels;
3591 void *closure;
3593 return 1;
3596 #endif /* ALLOC_XPM_COLORS */
3599 #ifdef HAVE_NTGUI
3601 /* XPM library details. */
3603 DEF_IMGLIB_FN (XpmFreeAttributes);
3604 DEF_IMGLIB_FN (XpmCreateImageFromBuffer);
3605 DEF_IMGLIB_FN (XpmReadFileToImage);
3606 DEF_IMGLIB_FN (XImageFree);
3608 static int
3609 init_xpm_functions (Lisp_Object libraries)
3611 HMODULE library;
3613 if (!(library = w32_delayed_load (libraries, Qxpm)))
3614 return 0;
3616 LOAD_IMGLIB_FN (library, XpmFreeAttributes);
3617 LOAD_IMGLIB_FN (library, XpmCreateImageFromBuffer);
3618 LOAD_IMGLIB_FN (library, XpmReadFileToImage);
3619 LOAD_IMGLIB_FN (library, XImageFree);
3620 return 1;
3623 #endif /* HAVE_NTGUI */
3626 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
3627 for XPM images. Such a list must consist of conses whose car and
3628 cdr are strings. */
3630 static int
3631 xpm_valid_color_symbols_p (color_symbols)
3632 Lisp_Object color_symbols;
3634 while (CONSP (color_symbols))
3636 Lisp_Object sym = XCAR (color_symbols);
3637 if (!CONSP (sym)
3638 || !STRINGP (XCAR (sym))
3639 || !STRINGP (XCDR (sym)))
3640 break;
3641 color_symbols = XCDR (color_symbols);
3644 return NILP (color_symbols);
3648 /* Value is non-zero if OBJECT is a valid XPM image specification. */
3650 static int
3651 xpm_image_p (object)
3652 Lisp_Object object;
3654 struct image_keyword fmt[XPM_LAST];
3655 bcopy (xpm_format, fmt, sizeof fmt);
3656 return (parse_image_spec (object, fmt, XPM_LAST, Qxpm)
3657 /* Either `:file' or `:data' must be present. */
3658 && fmt[XPM_FILE].count + fmt[XPM_DATA].count == 1
3659 /* Either no `:color-symbols' or it's a list of conses
3660 whose car and cdr are strings. */
3661 && (fmt[XPM_COLOR_SYMBOLS].count == 0
3662 || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
3665 #endif /* HAVE_XPM || HAVE_NS */
3667 #if defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
3669 x_create_bitmap_from_xpm_data (f, bits)
3670 struct frame *f;
3671 char **bits;
3673 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3674 int id, rc;
3675 XpmAttributes attrs;
3676 Pixmap bitmap, mask;
3678 bzero (&attrs, sizeof attrs);
3680 attrs.visual = FRAME_X_VISUAL (f);
3681 attrs.colormap = FRAME_X_COLORMAP (f);
3682 attrs.valuemask |= XpmVisual;
3683 attrs.valuemask |= XpmColormap;
3685 rc = XpmCreatePixmapFromData (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3686 bits, &bitmap, &mask, &attrs);
3687 if (rc != XpmSuccess)
3689 XpmFreeAttributes (&attrs);
3690 return -1;
3693 id = x_allocate_bitmap_record (f);
3694 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
3695 dpyinfo->bitmaps[id - 1].have_mask = 1;
3696 dpyinfo->bitmaps[id - 1].mask = mask;
3697 dpyinfo->bitmaps[id - 1].file = NULL;
3698 dpyinfo->bitmaps[id - 1].height = attrs.height;
3699 dpyinfo->bitmaps[id - 1].width = attrs.width;
3700 dpyinfo->bitmaps[id - 1].depth = attrs.depth;
3701 dpyinfo->bitmaps[id - 1].refcount = 1;
3703 XpmFreeAttributes (&attrs);
3704 return id;
3706 #endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */
3708 /* Load image IMG which will be displayed on frame F. Value is
3709 non-zero if successful. */
3711 #ifdef HAVE_XPM
3713 static int
3714 xpm_load (f, img)
3715 struct frame *f;
3716 struct image *img;
3718 int rc;
3719 XpmAttributes attrs;
3720 Lisp_Object specified_file, color_symbols;
3721 #ifdef HAVE_NTGUI
3722 HDC hdc;
3723 xpm_XImage * xpm_image = NULL, * xpm_mask = NULL;
3724 #endif /* HAVE_NTGUI */
3726 /* Configure the XPM lib. Use the visual of frame F. Allocate
3727 close colors. Return colors allocated. */
3728 bzero (&attrs, sizeof attrs);
3730 #ifndef HAVE_NTGUI
3731 attrs.visual = FRAME_X_VISUAL (f);
3732 attrs.colormap = FRAME_X_COLORMAP (f);
3733 attrs.valuemask |= XpmVisual;
3734 attrs.valuemask |= XpmColormap;
3735 #endif /* HAVE_NTGUI */
3737 #ifdef ALLOC_XPM_COLORS
3738 /* Allocate colors with our own functions which handle
3739 failing color allocation more gracefully. */
3740 attrs.color_closure = f;
3741 attrs.alloc_color = xpm_alloc_color;
3742 attrs.free_colors = xpm_free_colors;
3743 attrs.valuemask |= XpmAllocColor | XpmFreeColors | XpmColorClosure;
3744 #else /* not ALLOC_XPM_COLORS */
3745 /* Let the XPM lib allocate colors. */
3746 attrs.valuemask |= XpmReturnAllocPixels;
3747 #ifdef XpmAllocCloseColors
3748 attrs.alloc_close_colors = 1;
3749 attrs.valuemask |= XpmAllocCloseColors;
3750 #else /* not XpmAllocCloseColors */
3751 attrs.closeness = 600;
3752 attrs.valuemask |= XpmCloseness;
3753 #endif /* not XpmAllocCloseColors */
3754 #endif /* ALLOC_XPM_COLORS */
3756 /* If image specification contains symbolic color definitions, add
3757 these to `attrs'. */
3758 color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL);
3759 if (CONSP (color_symbols))
3761 Lisp_Object tail;
3762 XpmColorSymbol *xpm_syms;
3763 int i, size;
3765 attrs.valuemask |= XpmColorSymbols;
3767 /* Count number of symbols. */
3768 attrs.numsymbols = 0;
3769 for (tail = color_symbols; CONSP (tail); tail = XCDR (tail))
3770 ++attrs.numsymbols;
3772 /* Allocate an XpmColorSymbol array. */
3773 size = attrs.numsymbols * sizeof *xpm_syms;
3774 xpm_syms = (XpmColorSymbol *) alloca (size);
3775 bzero (xpm_syms, size);
3776 attrs.colorsymbols = xpm_syms;
3778 /* Fill the color symbol array. */
3779 for (tail = color_symbols, i = 0;
3780 CONSP (tail);
3781 ++i, tail = XCDR (tail))
3783 Lisp_Object name = XCAR (XCAR (tail));
3784 Lisp_Object color = XCDR (XCAR (tail));
3785 xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1);
3786 strcpy (xpm_syms[i].name, SDATA (name));
3787 xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1);
3788 strcpy (xpm_syms[i].value, SDATA (color));
3792 /* Create a pixmap for the image, either from a file, or from a
3793 string buffer containing data in the same format as an XPM file. */
3794 #ifdef ALLOC_XPM_COLORS
3795 xpm_init_color_cache (f, &attrs);
3796 #endif
3798 specified_file = image_spec_value (img->spec, QCfile, NULL);
3800 #ifdef HAVE_NTGUI
3802 HDC frame_dc = get_frame_dc (f);
3803 hdc = CreateCompatibleDC (frame_dc);
3804 release_frame_dc (f, frame_dc);
3806 #endif /* HAVE_NTGUI */
3808 if (STRINGP (specified_file))
3810 Lisp_Object file = x_find_image_file (specified_file);
3811 if (!STRINGP (file))
3813 image_error ("Cannot find image file `%s'", specified_file, Qnil);
3814 return 0;
3817 #ifdef HAVE_NTGUI
3818 /* XpmReadFileToPixmap is not available in the Windows port of
3819 libxpm. But XpmReadFileToImage almost does what we want. */
3820 rc = fn_XpmReadFileToImage (&hdc, SDATA (file),
3821 &xpm_image, &xpm_mask,
3822 &attrs);
3823 #else
3824 rc = XpmReadFileToPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3825 SDATA (file), &img->pixmap, &img->mask,
3826 &attrs);
3827 #endif /* HAVE_NTGUI */
3829 else
3831 Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);
3832 #ifdef HAVE_NTGUI
3833 /* XpmCreatePixmapFromBuffer is not available in the Windows port
3834 of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
3835 rc = fn_XpmCreateImageFromBuffer (&hdc, SDATA (buffer),
3836 &xpm_image, &xpm_mask,
3837 &attrs);
3838 #else
3839 rc = XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3840 SDATA (buffer),
3841 &img->pixmap, &img->mask,
3842 &attrs);
3843 #endif /* HAVE_NTGUI */
3846 if (rc == XpmSuccess)
3848 #if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS)
3849 img->colors = colors_in_color_table (&img->ncolors);
3850 #else /* not ALLOC_XPM_COLORS */
3851 int i;
3853 #ifdef HAVE_NTGUI
3854 /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
3855 plus some duplicate attributes. */
3856 if (xpm_image && xpm_image->bitmap)
3858 img->pixmap = xpm_image->bitmap;
3859 /* XImageFree in libXpm frees XImage struct without destroying
3860 the bitmap, which is what we want. */
3861 fn_XImageFree (xpm_image);
3863 if (xpm_mask && xpm_mask->bitmap)
3865 /* The mask appears to be inverted compared with what we expect.
3866 TODO: invert our expectations. See other places where we
3867 have to invert bits because our idea of masks is backwards. */
3868 HGDIOBJ old_obj;
3869 old_obj = SelectObject (hdc, xpm_mask->bitmap);
3871 PatBlt (hdc, 0, 0, xpm_mask->width, xpm_mask->height, DSTINVERT);
3872 SelectObject (hdc, old_obj);
3874 img->mask = xpm_mask->bitmap;
3875 fn_XImageFree (xpm_mask);
3876 DeleteDC (hdc);
3879 DeleteDC (hdc);
3880 #endif /* HAVE_NTGUI */
3882 /* Remember allocated colors. */
3883 img->ncolors = attrs.nalloc_pixels;
3884 img->colors = (unsigned long *) xmalloc (img->ncolors
3885 * sizeof *img->colors);
3886 for (i = 0; i < attrs.nalloc_pixels; ++i)
3888 img->colors[i] = attrs.alloc_pixels[i];
3889 #ifdef DEBUG_X_COLORS
3890 register_color (img->colors[i]);
3891 #endif
3893 #endif /* not ALLOC_XPM_COLORS */
3895 img->width = attrs.width;
3896 img->height = attrs.height;
3897 xassert (img->width > 0 && img->height > 0);
3899 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
3900 #ifdef HAVE_NTGUI
3901 fn_XpmFreeAttributes (&attrs);
3902 #else
3903 XpmFreeAttributes (&attrs);
3904 #endif /* HAVE_NTGUI */
3906 else
3908 #ifdef HAVE_NTGUI
3909 DeleteDC (hdc);
3910 #endif /* HAVE_NTGUI */
3912 switch (rc)
3914 case XpmOpenFailed:
3915 image_error ("Error opening XPM file (%s)", img->spec, Qnil);
3916 break;
3918 case XpmFileInvalid:
3919 image_error ("Invalid XPM file (%s)", img->spec, Qnil);
3920 break;
3922 case XpmNoMemory:
3923 image_error ("Out of memory (%s)", img->spec, Qnil);
3924 break;
3926 case XpmColorFailed:
3927 image_error ("Color allocation error (%s)", img->spec, Qnil);
3928 break;
3930 default:
3931 image_error ("Unknown error (%s)", img->spec, Qnil);
3932 break;
3936 #ifdef ALLOC_XPM_COLORS
3937 xpm_free_color_cache ();
3938 #endif
3939 return rc == XpmSuccess;
3942 #endif /* HAVE_XPM */
3944 #if defined (HAVE_NS) && !defined (HAVE_XPM)
3946 /* XPM support functions for NS where libxpm is not available.
3947 Only XPM version 3 (without any extensions) is supported. */
3949 static int xpm_scan P_ ((const unsigned char **, const unsigned char *,
3950 const unsigned char **, int *));
3951 static Lisp_Object xpm_make_color_table_v
3952 P_ ((void (**) (Lisp_Object, const unsigned char *, int, Lisp_Object),
3953 Lisp_Object (**) (Lisp_Object, const unsigned char *, int)));
3954 static void xpm_put_color_table_v P_ ((Lisp_Object, const unsigned char *,
3955 int, Lisp_Object));
3956 static Lisp_Object xpm_get_color_table_v P_ ((Lisp_Object,
3957 const unsigned char *, int));
3958 static Lisp_Object xpm_make_color_table_h
3959 P_ ((void (**) (Lisp_Object, const unsigned char *, int, Lisp_Object),
3960 Lisp_Object (**) (Lisp_Object, const unsigned char *, int)));
3961 static void xpm_put_color_table_h P_ ((Lisp_Object, const unsigned char *,
3962 int, Lisp_Object));
3963 static Lisp_Object xpm_get_color_table_h P_ ((Lisp_Object,
3964 const unsigned char *, int));
3965 static int xpm_str_to_color_key P_ ((const char *));
3966 static int xpm_load_image P_ ((struct frame *, struct image *,
3967 const unsigned char *, const unsigned char *));
3969 /* Tokens returned from xpm_scan. */
3971 enum xpm_token
3973 XPM_TK_IDENT = 256,
3974 XPM_TK_STRING,
3975 XPM_TK_EOF
3978 /* Scan an XPM data and return a character (< 256) or a token defined
3979 by enum xpm_token above. *S and END are the start (inclusive) and
3980 the end (exclusive) addresses of the data, respectively. Advance
3981 *S while scanning. If token is either XPM_TK_IDENT or
3982 XPM_TK_STRING, *BEG and *LEN are set to the start address and the
3983 length of the corresponding token, respectively. */
3985 static int
3986 xpm_scan (s, end, beg, len)
3987 const unsigned char **s, *end, **beg;
3988 int *len;
3990 int c;
3992 while (*s < end)
3994 /* Skip white-space. */
3995 while (*s < end && (c = *(*s)++, isspace (c)))
3998 /* gnus-pointer.xpm uses '-' in its identifier.
3999 sb-dir-plus.xpm uses '+' in its identifier. */
4000 if (isalpha (c) || c == '_' || c == '-' || c == '+')
4002 *beg = *s - 1;
4003 while (*s < end
4004 && (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+'))
4005 ++*s;
4006 *len = *s - *beg;
4007 return XPM_TK_IDENT;
4009 else if (c == '"')
4011 *beg = *s;
4012 while (*s < end && **s != '"')
4013 ++*s;
4014 *len = *s - *beg;
4015 if (*s < end)
4016 ++*s;
4017 return XPM_TK_STRING;
4019 else if (c == '/')
4021 if (*s < end && **s == '*')
4023 /* C-style comment. */
4024 ++*s;
4027 while (*s < end && *(*s)++ != '*')
4030 while (*s < end && **s != '/');
4031 if (*s < end)
4032 ++*s;
4034 else
4035 return c;
4037 else
4038 return c;
4041 return XPM_TK_EOF;
4044 /* Functions for color table lookup in XPM data. A key is a string
4045 specifying the color of each pixel in XPM data. A value is either
4046 an integer that specifies a pixel color, Qt that specifies
4047 transparency, or Qnil for the unspecified color. If the length of
4048 the key string is one, a vector is used as a table. Otherwise, a
4049 hash table is used. */
4051 static Lisp_Object
4052 xpm_make_color_table_v (put_func, get_func)
4053 void (**put_func) (Lisp_Object, const unsigned char *, int, Lisp_Object);
4054 Lisp_Object (**get_func) (Lisp_Object, const unsigned char *, int);
4056 *put_func = xpm_put_color_table_v;
4057 *get_func = xpm_get_color_table_v;
4058 return Fmake_vector (make_number (256), Qnil);
4061 static void
4062 xpm_put_color_table_v (color_table, chars_start, chars_len, color)
4063 Lisp_Object color_table;
4064 const unsigned char *chars_start;
4065 int chars_len;
4066 Lisp_Object color;
4068 XVECTOR (color_table)->contents[*chars_start] = color;
4071 static Lisp_Object
4072 xpm_get_color_table_v (color_table, chars_start, chars_len)
4073 Lisp_Object color_table;
4074 const unsigned char *chars_start;
4075 int chars_len;
4077 return XVECTOR (color_table)->contents[*chars_start];
4080 static Lisp_Object
4081 xpm_make_color_table_h (put_func, get_func)
4082 void (**put_func) (Lisp_Object, const unsigned char *, int, Lisp_Object);
4083 Lisp_Object (**get_func) (Lisp_Object, const unsigned char *, int);
4085 *put_func = xpm_put_color_table_h;
4086 *get_func = xpm_get_color_table_h;
4087 return make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE),
4088 make_float (DEFAULT_REHASH_SIZE),
4089 make_float (DEFAULT_REHASH_THRESHOLD),
4090 Qnil, Qnil, Qnil);
4093 static void
4094 xpm_put_color_table_h (color_table, chars_start, chars_len, color)
4095 Lisp_Object color_table;
4096 const unsigned char *chars_start;
4097 int chars_len;
4098 Lisp_Object color;
4100 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
4101 unsigned hash_code;
4102 Lisp_Object chars = make_unibyte_string (chars_start, chars_len);
4104 hash_lookup (table, chars, &hash_code);
4105 hash_put (table, chars, color, hash_code);
4108 static Lisp_Object
4109 xpm_get_color_table_h (color_table, chars_start, chars_len)
4110 Lisp_Object color_table;
4111 const unsigned char *chars_start;
4112 int chars_len;
4114 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
4115 int i = hash_lookup (table, make_unibyte_string (chars_start, chars_len),
4116 NULL);
4118 return i >= 0 ? HASH_VALUE (table, i) : Qnil;
4121 enum xpm_color_key {
4122 XPM_COLOR_KEY_S,
4123 XPM_COLOR_KEY_M,
4124 XPM_COLOR_KEY_G4,
4125 XPM_COLOR_KEY_G,
4126 XPM_COLOR_KEY_C
4129 static const char xpm_color_key_strings[][4] = {"s", "m", "g4", "g", "c"};
4131 static int
4132 xpm_str_to_color_key (s)
4133 const char *s;
4135 int i;
4137 for (i = 0;
4138 i < sizeof xpm_color_key_strings / sizeof xpm_color_key_strings[0];
4139 i++)
4140 if (strcmp (xpm_color_key_strings[i], s) == 0)
4141 return i;
4142 return -1;
4145 static int
4146 xpm_load_image (f, img, contents, end)
4147 struct frame *f;
4148 struct image *img;
4149 const unsigned char *contents, *end;
4151 const unsigned char *s = contents, *beg, *str;
4152 unsigned char buffer[BUFSIZ];
4153 int width, height, x, y;
4154 int num_colors, chars_per_pixel;
4155 int len, LA1;
4156 void (*put_color_table) (Lisp_Object, const unsigned char *, int, Lisp_Object);
4157 Lisp_Object (*get_color_table) (Lisp_Object, const unsigned char *, int);
4158 Lisp_Object frame, color_symbols, color_table;
4159 int best_key, have_mask = 0;
4160 XImagePtr ximg = NULL, mask_img = NULL;
4162 #define match() \
4163 LA1 = xpm_scan (&s, end, &beg, &len)
4165 #define expect(TOKEN) \
4166 if (LA1 != (TOKEN)) \
4167 goto failure; \
4168 else \
4169 match ()
4171 #define expect_ident(IDENT) \
4172 if (LA1 == XPM_TK_IDENT \
4173 && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
4174 match (); \
4175 else \
4176 goto failure
4178 if (!(end - s >= 9 && memcmp (s, "/* XPM */", 9) == 0))
4179 goto failure;
4180 s += 9;
4181 match();
4182 expect_ident ("static");
4183 expect_ident ("char");
4184 expect ('*');
4185 expect (XPM_TK_IDENT);
4186 expect ('[');
4187 expect (']');
4188 expect ('=');
4189 expect ('{');
4190 expect (XPM_TK_STRING);
4191 if (len >= BUFSIZ)
4192 goto failure;
4193 memcpy (buffer, beg, len);
4194 buffer[len] = '\0';
4195 if (sscanf (buffer, "%d %d %d %d", &width, &height,
4196 &num_colors, &chars_per_pixel) != 4
4197 || width <= 0 || height <= 0
4198 || num_colors <= 0 || chars_per_pixel <= 0)
4199 goto failure;
4201 if (!check_image_size (f, width, height))
4203 image_error ("Invalid image size", Qnil, Qnil);
4204 goto failure;
4207 expect (',');
4209 XSETFRAME (frame, f);
4210 if (!NILP (Fxw_display_color_p (frame)))
4211 best_key = XPM_COLOR_KEY_C;
4212 else if (!NILP (Fx_display_grayscale_p (frame)))
4213 best_key = (XFASTINT (Fx_display_planes (frame)) > 2
4214 ? XPM_COLOR_KEY_G : XPM_COLOR_KEY_G4);
4215 else
4216 best_key = XPM_COLOR_KEY_M;
4218 color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL);
4219 if (chars_per_pixel == 1)
4220 color_table = xpm_make_color_table_v (&put_color_table,
4221 &get_color_table);
4222 else
4223 color_table = xpm_make_color_table_h (&put_color_table,
4224 &get_color_table);
4226 while (num_colors-- > 0)
4228 unsigned char *color, *max_color;
4229 int key, next_key, max_key = 0;
4230 Lisp_Object symbol_color = Qnil, color_val;
4231 XColor cdef;
4233 expect (XPM_TK_STRING);
4234 if (len <= chars_per_pixel || len >= BUFSIZ + chars_per_pixel)
4235 goto failure;
4236 memcpy (buffer, beg + chars_per_pixel, len - chars_per_pixel);
4237 buffer[len - chars_per_pixel] = '\0';
4239 str = strtok (buffer, " \t");
4240 if (str == NULL)
4241 goto failure;
4242 key = xpm_str_to_color_key (str);
4243 if (key < 0)
4244 goto failure;
4247 color = strtok (NULL, " \t");
4248 if (color == NULL)
4249 goto failure;
4251 while ((str = strtok (NULL, " \t")) != NULL)
4253 next_key = xpm_str_to_color_key (str);
4254 if (next_key >= 0)
4255 break;
4256 color[strlen (color)] = ' ';
4259 if (key == XPM_COLOR_KEY_S)
4261 if (NILP (symbol_color))
4262 symbol_color = build_string (color);
4264 else if (max_key < key && key <= best_key)
4266 max_key = key;
4267 max_color = color;
4269 key = next_key;
4271 while (str);
4273 color_val = Qnil;
4274 if (!NILP (color_symbols) && !NILP (symbol_color))
4276 Lisp_Object specified_color = Fassoc (symbol_color, color_symbols);
4278 if (CONSP (specified_color) && STRINGP (XCDR (specified_color)))
4280 if (xstrcasecmp (SDATA (XCDR (specified_color)), "None") == 0)
4281 color_val = Qt;
4282 else if (x_defined_color (f, SDATA (XCDR (specified_color)),
4283 &cdef, 0))
4284 color_val = make_number (cdef.pixel);
4287 if (NILP (color_val) && max_key > 0)
4289 if (xstrcasecmp (max_color, "None") == 0)
4290 color_val = Qt;
4291 else if (x_defined_color (f, max_color, &cdef, 0))
4292 color_val = make_number (cdef.pixel);
4294 if (!NILP (color_val))
4295 (*put_color_table) (color_table, beg, chars_per_pixel, color_val);
4297 expect (',');
4300 if (!x_create_x_image_and_pixmap (f, width, height, 0,
4301 &ximg, &img->pixmap)
4302 #ifndef HAVE_NS
4303 || !x_create_x_image_and_pixmap (f, width, height, 1,
4304 &mask_img, &img->mask)
4305 #endif
4308 image_error ("Out of memory (%s)", img->spec, Qnil);
4309 goto error;
4312 for (y = 0; y < height; y++)
4314 expect (XPM_TK_STRING);
4315 str = beg;
4316 if (len < width * chars_per_pixel)
4317 goto failure;
4318 for (x = 0; x < width; x++, str += chars_per_pixel)
4320 Lisp_Object color_val =
4321 (*get_color_table) (color_table, str, chars_per_pixel);
4323 XPutPixel (ximg, x, y,
4324 (INTEGERP (color_val) ? XINT (color_val)
4325 : FRAME_FOREGROUND_PIXEL (f)));
4326 #ifndef HAVE_NS
4327 XPutPixel (mask_img, x, y,
4328 (!EQ (color_val, Qt) ? PIX_MASK_DRAW
4329 : (have_mask = 1, PIX_MASK_RETAIN)));
4330 #else
4331 if (EQ(color_val, Qt))
4332 ns_set_alpha(ximg, x, y, 0);
4333 #endif
4335 if (y + 1 < height)
4336 expect (',');
4339 img->width = width;
4340 img->height = height;
4342 /* Maybe fill in the background field while we have ximg handy. */
4343 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
4344 IMAGE_BACKGROUND (img, f, ximg);
4346 x_put_x_image (f, ximg, img->pixmap, width, height);
4347 x_destroy_x_image (ximg);
4348 #ifndef HAVE_NS
4349 if (have_mask)
4351 /* Fill in the background_transparent field while we have the
4352 mask handy. */
4353 image_background_transparent (img, f, mask_img);
4355 x_put_x_image (f, mask_img, img->mask, width, height);
4356 x_destroy_x_image (mask_img);
4358 else
4360 x_destroy_x_image (mask_img);
4361 Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
4362 img->mask = NO_PIXMAP;
4364 #endif
4365 return 1;
4367 failure:
4368 image_error ("Invalid XPM file (%s)", img->spec, Qnil);
4369 error:
4370 x_destroy_x_image (ximg);
4371 x_destroy_x_image (mask_img);
4372 x_clear_image (f, img);
4373 return 0;
4375 #undef match
4376 #undef expect
4377 #undef expect_ident
4380 static int
4381 xpm_load (f, img)
4382 struct frame *f;
4383 struct image *img;
4385 int success_p = 0;
4386 Lisp_Object file_name;
4388 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4389 file_name = image_spec_value (img->spec, QCfile, NULL);
4390 if (STRINGP (file_name))
4392 Lisp_Object file;
4393 unsigned char *contents;
4394 int size;
4395 struct gcpro gcpro1;
4397 file = x_find_image_file (file_name);
4398 GCPRO1 (file);
4399 if (!STRINGP (file))
4401 image_error ("Cannot find image file `%s'", file_name, Qnil);
4402 UNGCPRO;
4403 return 0;
4406 contents = slurp_file (SDATA (file), &size);
4407 if (contents == NULL)
4409 image_error ("Error loading XPM image `%s'", img->spec, Qnil);
4410 UNGCPRO;
4411 return 0;
4414 success_p = xpm_load_image (f, img, contents, contents + size);
4415 xfree (contents);
4416 UNGCPRO;
4418 else
4420 Lisp_Object data;
4422 data = image_spec_value (img->spec, QCdata, NULL);
4423 success_p = xpm_load_image (f, img, SDATA (data),
4424 SDATA (data) + SBYTES (data));
4427 return success_p;
4430 #endif /* HAVE_NS && !HAVE_XPM */
4434 /***********************************************************************
4435 Color table
4436 ***********************************************************************/
4438 #ifdef COLOR_TABLE_SUPPORT
4440 /* An entry in the color table mapping an RGB color to a pixel color. */
4442 struct ct_color
4444 int r, g, b;
4445 unsigned long pixel;
4447 /* Next in color table collision list. */
4448 struct ct_color *next;
4451 /* The bucket vector size to use. Must be prime. */
4453 #define CT_SIZE 101
4455 /* Value is a hash of the RGB color given by R, G, and B. */
4457 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
4459 /* The color hash table. */
4461 struct ct_color **ct_table;
4463 /* Number of entries in the color table. */
4465 int ct_colors_allocated;
4467 /* Initialize the color table. */
4469 static void
4470 init_color_table ()
4472 int size = CT_SIZE * sizeof (*ct_table);
4473 ct_table = (struct ct_color **) xmalloc (size);
4474 bzero (ct_table, size);
4475 ct_colors_allocated = 0;
4479 /* Free memory associated with the color table. */
4481 static void
4482 free_color_table ()
4484 int i;
4485 struct ct_color *p, *next;
4487 for (i = 0; i < CT_SIZE; ++i)
4488 for (p = ct_table[i]; p; p = next)
4490 next = p->next;
4491 xfree (p);
4494 xfree (ct_table);
4495 ct_table = NULL;
4499 /* Value is a pixel color for RGB color R, G, B on frame F. If an
4500 entry for that color already is in the color table, return the
4501 pixel color of that entry. Otherwise, allocate a new color for R,
4502 G, B, and make an entry in the color table. */
4504 static unsigned long
4505 lookup_rgb_color (f, r, g, b)
4506 struct frame *f;
4507 int r, g, b;
4509 unsigned hash = CT_HASH_RGB (r, g, b);
4510 int i = hash % CT_SIZE;
4511 struct ct_color *p;
4512 Display_Info *dpyinfo;
4514 /* Handle TrueColor visuals specially, which improves performance by
4515 two orders of magnitude. Freeing colors on TrueColor visuals is
4516 a nop, and pixel colors specify RGB values directly. See also
4517 the Xlib spec, chapter 3.1. */
4518 dpyinfo = FRAME_X_DISPLAY_INFO (f);
4519 if (dpyinfo->red_bits > 0)
4521 unsigned long pr, pg, pb;
4523 /* Apply gamma-correction like normal color allocation does. */
4524 if (f->gamma)
4526 XColor color;
4527 color.red = r, color.green = g, color.blue = b;
4528 gamma_correct (f, &color);
4529 r = color.red, g = color.green, b = color.blue;
4532 /* Scale down RGB values to the visual's bits per RGB, and shift
4533 them to the right position in the pixel color. Note that the
4534 original RGB values are 16-bit values, as usual in X. */
4535 pr = (r >> (16 - dpyinfo->red_bits)) << dpyinfo->red_offset;
4536 pg = (g >> (16 - dpyinfo->green_bits)) << dpyinfo->green_offset;
4537 pb = (b >> (16 - dpyinfo->blue_bits)) << dpyinfo->blue_offset;
4539 /* Assemble the pixel color. */
4540 return pr | pg | pb;
4543 for (p = ct_table[i]; p; p = p->next)
4544 if (p->r == r && p->g == g && p->b == b)
4545 break;
4547 if (p == NULL)
4550 #ifdef HAVE_X_WINDOWS
4551 XColor color;
4552 Colormap cmap;
4553 int rc;
4555 color.red = r;
4556 color.green = g;
4557 color.blue = b;
4559 cmap = FRAME_X_COLORMAP (f);
4560 rc = x_alloc_nearest_color (f, cmap, &color);
4561 if (rc)
4563 ++ct_colors_allocated;
4564 p = (struct ct_color *) xmalloc (sizeof *p);
4565 p->r = r;
4566 p->g = g;
4567 p->b = b;
4568 p->pixel = color.pixel;
4569 p->next = ct_table[i];
4570 ct_table[i] = p;
4572 else
4573 return FRAME_FOREGROUND_PIXEL (f);
4575 #else
4576 COLORREF color;
4577 #ifdef HAVE_NTGUI
4578 color = PALETTERGB (r, g, b);
4579 #else
4580 color = RGB_TO_ULONG (r, g, b);
4581 #endif /* HAVE_NTGUI */
4582 ++ct_colors_allocated;
4583 p = (struct ct_color *) xmalloc (sizeof *p);
4584 p->r = r;
4585 p->g = g;
4586 p->b = b;
4587 p->pixel = color;
4588 p->next = ct_table[i];
4589 ct_table[i] = p;
4590 #endif /* HAVE_X_WINDOWS */
4594 return p->pixel;
4598 /* Look up pixel color PIXEL which is used on frame F in the color
4599 table. If not already present, allocate it. Value is PIXEL. */
4601 static unsigned long
4602 lookup_pixel_color (f, pixel)
4603 struct frame *f;
4604 unsigned long pixel;
4606 int i = pixel % CT_SIZE;
4607 struct ct_color *p;
4609 for (p = ct_table[i]; p; p = p->next)
4610 if (p->pixel == pixel)
4611 break;
4613 if (p == NULL)
4615 XColor color;
4616 Colormap cmap;
4617 int rc;
4619 #ifdef HAVE_X_WINDOWS
4620 cmap = FRAME_X_COLORMAP (f);
4621 color.pixel = pixel;
4622 x_query_color (f, &color);
4623 rc = x_alloc_nearest_color (f, cmap, &color);
4624 #else
4625 BLOCK_INPUT;
4626 cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f));
4627 color.pixel = pixel;
4628 XQueryColor (NULL, cmap, &color);
4629 rc = x_alloc_nearest_color (f, cmap, &color);
4630 UNBLOCK_INPUT;
4631 #endif /* HAVE_X_WINDOWS */
4633 if (rc)
4635 ++ct_colors_allocated;
4637 p = (struct ct_color *) xmalloc (sizeof *p);
4638 p->r = color.red;
4639 p->g = color.green;
4640 p->b = color.blue;
4641 p->pixel = pixel;
4642 p->next = ct_table[i];
4643 ct_table[i] = p;
4645 else
4646 return FRAME_FOREGROUND_PIXEL (f);
4648 return p->pixel;
4652 /* Value is a vector of all pixel colors contained in the color table,
4653 allocated via xmalloc. Set *N to the number of colors. */
4655 static unsigned long *
4656 colors_in_color_table (n)
4657 int *n;
4659 int i, j;
4660 struct ct_color *p;
4661 unsigned long *colors;
4663 if (ct_colors_allocated == 0)
4665 *n = 0;
4666 colors = NULL;
4668 else
4670 colors = (unsigned long *) xmalloc (ct_colors_allocated
4671 * sizeof *colors);
4672 *n = ct_colors_allocated;
4674 for (i = j = 0; i < CT_SIZE; ++i)
4675 for (p = ct_table[i]; p; p = p->next)
4676 colors[j++] = p->pixel;
4679 return colors;
4682 #else /* COLOR_TABLE_SUPPORT */
4684 static unsigned long
4685 lookup_rgb_color (f, r, g, b)
4686 struct frame *f;
4687 int r, g, b;
4689 unsigned long pixel;
4691 #ifdef HAVE_NTGUI
4692 pixel = PALETTERGB (r >> 8, g >> 8, b >> 8);
4693 #endif /* HAVE_NTGUI */
4695 #ifdef HAVE_NS
4696 pixel = RGB_TO_ULONG (r >> 8, g >> 8, b >> 8);
4697 #endif /* HAVE_NS */
4698 return pixel;
4701 static void
4702 init_color_table ()
4705 #endif /* COLOR_TABLE_SUPPORT */
4708 /***********************************************************************
4709 Algorithms
4710 ***********************************************************************/
4712 static XColor *x_to_xcolors P_ ((struct frame *, struct image *, int));
4713 static void x_from_xcolors P_ ((struct frame *, struct image *, XColor *));
4714 static void x_detect_edges P_ ((struct frame *, struct image *, int[9], int));
4716 #ifdef HAVE_NTGUI
4717 static void XPutPixel (XImagePtr , int, int, COLORREF);
4718 #endif /* HAVE_NTGUI */
4720 /* Non-zero means draw a cross on images having `:conversion
4721 disabled'. */
4723 int cross_disabled_images;
4725 /* Edge detection matrices for different edge-detection
4726 strategies. */
4728 static int emboss_matrix[9] = {
4729 /* x - 1 x x + 1 */
4730 2, -1, 0, /* y - 1 */
4731 -1, 0, 1, /* y */
4732 0, 1, -2 /* y + 1 */
4735 static int laplace_matrix[9] = {
4736 /* x - 1 x x + 1 */
4737 1, 0, 0, /* y - 1 */
4738 0, 0, 0, /* y */
4739 0, 0, -1 /* y + 1 */
4742 /* Value is the intensity of the color whose red/green/blue values
4743 are R, G, and B. */
4745 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
4748 /* On frame F, return an array of XColor structures describing image
4749 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
4750 non-zero means also fill the red/green/blue members of the XColor
4751 structures. Value is a pointer to the array of XColors structures,
4752 allocated with xmalloc; it must be freed by the caller. */
4754 static XColor *
4755 x_to_xcolors (f, img, rgb_p)
4756 struct frame *f;
4757 struct image *img;
4758 int rgb_p;
4760 int x, y;
4761 XColor *colors, *p;
4762 XImagePtr_or_DC ximg;
4763 #ifdef HAVE_NTGUI
4764 HDC hdc;
4765 HGDIOBJ prev;
4766 #endif /* HAVE_NTGUI */
4768 colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors);
4770 #ifndef HAVE_NTGUI
4771 /* Get the X image IMG->pixmap. */
4772 ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
4773 0, 0, img->width, img->height, ~0, ZPixmap);
4774 #else
4775 /* Load the image into a memory device context. */
4776 hdc = get_frame_dc (f);
4777 ximg = CreateCompatibleDC (hdc);
4778 release_frame_dc (f, hdc);
4779 prev = SelectObject (ximg, img->pixmap);
4780 #endif /* HAVE_NTGUI */
4782 /* Fill the `pixel' members of the XColor array. I wished there
4783 were an easy and portable way to circumvent XGetPixel. */
4784 p = colors;
4785 for (y = 0; y < img->height; ++y)
4787 XColor *row = p;
4789 #ifdef HAVE_X_WINDOWS
4790 for (x = 0; x < img->width; ++x, ++p)
4791 p->pixel = XGetPixel (ximg, x, y);
4792 if (rgb_p)
4793 x_query_colors (f, row, img->width);
4795 #else
4797 for (x = 0; x < img->width; ++x, ++p)
4799 /* W32_TODO: palette support needed here? */
4800 p->pixel = GET_PIXEL (ximg, x, y);
4801 if (rgb_p)
4803 #if defined (HAVE_NS)
4804 p->red = RED16_FROM_ULONG (p->pixel);
4805 p->green = GREEN16_FROM_ULONG (p->pixel);
4806 p->blue = BLUE16_FROM_ULONG (p->pixel);
4807 #endif /* HAVE_NS */
4808 #ifdef HAVE_NTGUI
4809 p->red = 256 * GetRValue (p->pixel);
4810 p->green = 256 * GetGValue (p->pixel);
4811 p->blue = 256 * GetBValue (p->pixel);
4812 #endif /* HAVE_NTGUI */
4815 #endif /* HAVE_X_WINDOWS */
4818 Destroy_Image (ximg, prev);
4820 return colors;
4823 #ifdef HAVE_NTGUI
4825 /* Put a pixel of COLOR at position X, Y in XIMG. XIMG must have been
4826 created with CreateDIBSection, with the pointer to the bit values
4827 stored in ximg->data. */
4829 static void
4830 XPutPixel (ximg, x, y, color)
4831 XImagePtr ximg;
4832 int x, y;
4833 COLORREF color;
4835 int width = ximg->info.bmiHeader.biWidth;
4836 int height = ximg->info.bmiHeader.biHeight;
4837 unsigned char * pixel;
4839 /* True color images. */
4840 if (ximg->info.bmiHeader.biBitCount == 24)
4842 int rowbytes = width * 3;
4843 /* Ensure scanlines are aligned on 4 byte boundaries. */
4844 if (rowbytes % 4)
4845 rowbytes += 4 - (rowbytes % 4);
4847 pixel = ximg->data + y * rowbytes + x * 3;
4848 /* Windows bitmaps are in BGR order. */
4849 *pixel = GetBValue (color);
4850 *(pixel + 1) = GetGValue (color);
4851 *(pixel + 2) = GetRValue (color);
4853 /* Monochrome images. */
4854 else if (ximg->info.bmiHeader.biBitCount == 1)
4856 int rowbytes = width / 8;
4857 /* Ensure scanlines are aligned on 4 byte boundaries. */
4858 if (rowbytes % 4)
4859 rowbytes += 4 - (rowbytes % 4);
4860 pixel = ximg->data + y * rowbytes + x / 8;
4861 /* Filter out palette info. */
4862 if (color & 0x00ffffff)
4863 *pixel = *pixel | (1 << x % 8);
4864 else
4865 *pixel = *pixel & ~(1 << x % 8);
4867 else
4868 image_error ("XPutPixel: palette image not supported", Qnil, Qnil);
4871 #endif /* HAVE_NTGUI */
4873 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
4874 RGB members are set. F is the frame on which this all happens.
4875 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
4877 static void
4878 x_from_xcolors (f, img, colors)
4879 struct frame *f;
4880 struct image *img;
4881 XColor *colors;
4883 int x, y;
4884 XImagePtr oimg = NULL;
4885 Pixmap pixmap;
4886 XColor *p;
4888 init_color_table ();
4890 x_create_x_image_and_pixmap (f, img->width, img->height, 0,
4891 &oimg, &pixmap);
4892 p = colors;
4893 for (y = 0; y < img->height; ++y)
4894 for (x = 0; x < img->width; ++x, ++p)
4896 unsigned long pixel;
4897 pixel = lookup_rgb_color (f, p->red, p->green, p->blue);
4898 XPutPixel (oimg, x, y, pixel);
4901 xfree (colors);
4902 x_clear_image_1 (f, img, 1, 0, 1);
4904 x_put_x_image (f, oimg, pixmap, img->width, img->height);
4905 x_destroy_x_image (oimg);
4906 img->pixmap = pixmap;
4907 #ifdef COLOR_TABLE_SUPPORT
4908 img->colors = colors_in_color_table (&img->ncolors);
4909 free_color_table ();
4910 #endif /* COLOR_TABLE_SUPPORT */
4914 /* On frame F, perform edge-detection on image IMG.
4916 MATRIX is a nine-element array specifying the transformation
4917 matrix. See emboss_matrix for an example.
4919 COLOR_ADJUST is a color adjustment added to each pixel of the
4920 outgoing image. */
4922 static void
4923 x_detect_edges (f, img, matrix, color_adjust)
4924 struct frame *f;
4925 struct image *img;
4926 int matrix[9], color_adjust;
4928 XColor *colors = x_to_xcolors (f, img, 1);
4929 XColor *new, *p;
4930 int x, y, i, sum;
4932 for (i = sum = 0; i < 9; ++i)
4933 sum += eabs (matrix[i]);
4935 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
4937 new = (XColor *) xmalloc (img->width * img->height * sizeof *new);
4939 for (y = 0; y < img->height; ++y)
4941 p = COLOR (new, 0, y);
4942 p->red = p->green = p->blue = 0xffff/2;
4943 p = COLOR (new, img->width - 1, y);
4944 p->red = p->green = p->blue = 0xffff/2;
4947 for (x = 1; x < img->width - 1; ++x)
4949 p = COLOR (new, x, 0);
4950 p->red = p->green = p->blue = 0xffff/2;
4951 p = COLOR (new, x, img->height - 1);
4952 p->red = p->green = p->blue = 0xffff/2;
4955 for (y = 1; y < img->height - 1; ++y)
4957 p = COLOR (new, 1, y);
4959 for (x = 1; x < img->width - 1; ++x, ++p)
4961 int r, g, b, y1, x1;
4963 r = g = b = i = 0;
4964 for (y1 = y - 1; y1 < y + 2; ++y1)
4965 for (x1 = x - 1; x1 < x + 2; ++x1, ++i)
4966 if (matrix[i])
4968 XColor *t = COLOR (colors, x1, y1);
4969 r += matrix[i] * t->red;
4970 g += matrix[i] * t->green;
4971 b += matrix[i] * t->blue;
4974 r = (r / sum + color_adjust) & 0xffff;
4975 g = (g / sum + color_adjust) & 0xffff;
4976 b = (b / sum + color_adjust) & 0xffff;
4977 p->red = p->green = p->blue = COLOR_INTENSITY (r, g, b);
4981 xfree (colors);
4982 x_from_xcolors (f, img, new);
4984 #undef COLOR
4988 /* Perform the pre-defined `emboss' edge-detection on image IMG
4989 on frame F. */
4991 static void
4992 x_emboss (f, img)
4993 struct frame *f;
4994 struct image *img;
4996 x_detect_edges (f, img, emboss_matrix, 0xffff / 2);
5000 /* Transform image IMG which is used on frame F with a Laplace
5001 edge-detection algorithm. The result is an image that can be used
5002 to draw disabled buttons, for example. */
5004 static void
5005 x_laplace (f, img)
5006 struct frame *f;
5007 struct image *img;
5009 x_detect_edges (f, img, laplace_matrix, 45000);
5013 /* Perform edge-detection on image IMG on frame F, with specified
5014 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
5016 MATRIX must be either
5018 - a list of at least 9 numbers in row-major form
5019 - a vector of at least 9 numbers
5021 COLOR_ADJUST nil means use a default; otherwise it must be a
5022 number. */
5024 static void
5025 x_edge_detection (f, img, matrix, color_adjust)
5026 struct frame *f;
5027 struct image *img;
5028 Lisp_Object matrix, color_adjust;
5030 int i = 0;
5031 int trans[9];
5033 if (CONSP (matrix))
5035 for (i = 0;
5036 i < 9 && CONSP (matrix) && NUMBERP (XCAR (matrix));
5037 ++i, matrix = XCDR (matrix))
5038 trans[i] = XFLOATINT (XCAR (matrix));
5040 else if (VECTORP (matrix) && ASIZE (matrix) >= 9)
5042 for (i = 0; i < 9 && NUMBERP (AREF (matrix, i)); ++i)
5043 trans[i] = XFLOATINT (AREF (matrix, i));
5046 if (NILP (color_adjust))
5047 color_adjust = make_number (0xffff / 2);
5049 if (i == 9 && NUMBERP (color_adjust))
5050 x_detect_edges (f, img, trans, (int) XFLOATINT (color_adjust));
5054 /* Transform image IMG on frame F so that it looks disabled. */
5056 static void
5057 x_disable_image (f, img)
5058 struct frame *f;
5059 struct image *img;
5061 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
5062 #ifdef HAVE_NTGUI
5063 int n_planes = dpyinfo->n_planes * dpyinfo->n_cbits;
5064 #else
5065 int n_planes = dpyinfo->n_planes;
5066 #endif /* HAVE_NTGUI */
5068 if (n_planes >= 2)
5070 /* Color (or grayscale). Convert to gray, and equalize. Just
5071 drawing such images with a stipple can look very odd, so
5072 we're using this method instead. */
5073 XColor *colors = x_to_xcolors (f, img, 1);
5074 XColor *p, *end;
5075 const int h = 15000;
5076 const int l = 30000;
5078 for (p = colors, end = colors + img->width * img->height;
5079 p < end;
5080 ++p)
5082 int i = COLOR_INTENSITY (p->red, p->green, p->blue);
5083 int i2 = (0xffff - h - l) * i / 0xffff + l;
5084 p->red = p->green = p->blue = i2;
5087 x_from_xcolors (f, img, colors);
5090 /* Draw a cross over the disabled image, if we must or if we
5091 should. */
5092 if (n_planes < 2 || cross_disabled_images)
5094 #ifndef HAVE_NTGUI
5095 Display *dpy = FRAME_X_DISPLAY (f);
5096 GC gc;
5098 #ifndef HAVE_NS //TODO: NS support, however this not needed for toolbars
5100 #define MaskForeground(f) WHITE_PIX_DEFAULT (f)
5102 gc = XCreateGC (dpy, img->pixmap, 0, NULL);
5103 XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f));
5104 XDrawLine (dpy, img->pixmap, gc, 0, 0,
5105 img->width - 1, img->height - 1);
5106 XDrawLine (dpy, img->pixmap, gc, 0, img->height - 1,
5107 img->width - 1, 0);
5108 XFreeGC (dpy, gc);
5110 if (img->mask)
5112 gc = XCreateGC (dpy, img->mask, 0, NULL);
5113 XSetForeground (dpy, gc, MaskForeground (f));
5114 XDrawLine (dpy, img->mask, gc, 0, 0,
5115 img->width - 1, img->height - 1);
5116 XDrawLine (dpy, img->mask, gc, 0, img->height - 1,
5117 img->width - 1, 0);
5118 XFreeGC (dpy, gc);
5120 #endif /* !HAVE_NS */
5121 #else
5122 HDC hdc, bmpdc;
5123 HGDIOBJ prev;
5125 hdc = get_frame_dc (f);
5126 bmpdc = CreateCompatibleDC (hdc);
5127 release_frame_dc (f, hdc);
5129 prev = SelectObject (bmpdc, img->pixmap);
5131 SetTextColor (bmpdc, BLACK_PIX_DEFAULT (f));
5132 MoveToEx (bmpdc, 0, 0, NULL);
5133 LineTo (bmpdc, img->width - 1, img->height - 1);
5134 MoveToEx (bmpdc, 0, img->height - 1, NULL);
5135 LineTo (bmpdc, img->width - 1, 0);
5137 if (img->mask)
5139 SelectObject (bmpdc, img->mask);
5140 SetTextColor (bmpdc, WHITE_PIX_DEFAULT (f));
5141 MoveToEx (bmpdc, 0, 0, NULL);
5142 LineTo (bmpdc, img->width - 1, img->height - 1);
5143 MoveToEx (bmpdc, 0, img->height - 1, NULL);
5144 LineTo (bmpdc, img->width - 1, 0);
5146 SelectObject (bmpdc, prev);
5147 DeleteDC (bmpdc);
5148 #endif /* HAVE_NTGUI */
5153 /* Build a mask for image IMG which is used on frame F. FILE is the
5154 name of an image file, for error messages. HOW determines how to
5155 determine the background color of IMG. If it is a list '(R G B)',
5156 with R, G, and B being integers >= 0, take that as the color of the
5157 background. Otherwise, determine the background color of IMG
5158 heuristically. Value is non-zero if successful. */
5160 static int
5161 x_build_heuristic_mask (f, img, how)
5162 struct frame *f;
5163 struct image *img;
5164 Lisp_Object how;
5166 XImagePtr_or_DC ximg;
5167 #ifndef HAVE_NTGUI
5168 XImagePtr mask_img;
5169 #else
5170 HDC frame_dc;
5171 HGDIOBJ prev;
5172 char *mask_img;
5173 int row_width;
5174 #endif /* HAVE_NTGUI */
5175 int x, y, rc, use_img_background;
5176 unsigned long bg = 0;
5178 if (img->mask)
5180 Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
5181 img->mask = NO_PIXMAP;
5182 img->background_transparent_valid = 0;
5185 #ifndef HAVE_NTGUI
5186 #ifndef HAVE_NS
5187 /* Create an image and pixmap serving as mask. */
5188 rc = x_create_x_image_and_pixmap (f, img->width, img->height, 1,
5189 &mask_img, &img->mask);
5190 if (!rc)
5191 return 0;
5192 #endif /* !HAVE_NS */
5194 /* Get the X image of IMG->pixmap. */
5195 ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap, 0, 0,
5196 img->width, img->height,
5197 ~0, ZPixmap);
5198 #else
5199 /* Create the bit array serving as mask. */
5200 row_width = (img->width + 7) / 8;
5201 mask_img = xmalloc (row_width * img->height);
5202 bzero (mask_img, row_width * img->height);
5204 /* Create a memory device context for IMG->pixmap. */
5205 frame_dc = get_frame_dc (f);
5206 ximg = CreateCompatibleDC (frame_dc);
5207 release_frame_dc (f, frame_dc);
5208 prev = SelectObject (ximg, img->pixmap);
5209 #endif /* HAVE_NTGUI */
5211 /* Determine the background color of ximg. If HOW is `(R G B)'
5212 take that as color. Otherwise, use the image's background color. */
5213 use_img_background = 1;
5215 if (CONSP (how))
5217 int rgb[3], i;
5219 for (i = 0; i < 3 && CONSP (how) && NATNUMP (XCAR (how)); ++i)
5221 rgb[i] = XFASTINT (XCAR (how)) & 0xffff;
5222 how = XCDR (how);
5225 if (i == 3 && NILP (how))
5227 char color_name[30];
5228 sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]);
5229 bg = (
5230 #ifdef HAVE_NTGUI
5231 0x00ffffff & /* Filter out palette info. */
5232 #endif /* HAVE_NTGUI */
5233 x_alloc_image_color (f, img, build_string (color_name), 0));
5234 use_img_background = 0;
5238 if (use_img_background)
5239 bg = four_corners_best (ximg, img->corners, img->width, img->height);
5241 /* Set all bits in mask_img to 1 whose color in ximg is different
5242 from the background color bg. */
5243 #ifndef HAVE_NTGUI
5244 for (y = 0; y < img->height; ++y)
5245 for (x = 0; x < img->width; ++x)
5246 #ifndef HAVE_NS
5247 XPutPixel (mask_img, x, y, (XGetPixel (ximg, x, y) != bg
5248 ? PIX_MASK_DRAW : PIX_MASK_RETAIN));
5249 #else
5250 if (XGetPixel (ximg, x, y) == bg)
5251 ns_set_alpha(ximg, x, y, 0);
5252 #endif /* HAVE_NS */
5253 #ifndef HAVE_NS
5254 /* Fill in the background_transparent field while we have the mask handy. */
5255 image_background_transparent (img, f, mask_img);
5257 /* Put mask_img into img->mask. */
5258 x_put_x_image (f, mask_img, img->mask, img->width, img->height);
5259 x_destroy_x_image (mask_img);
5260 #endif /* !HAVE_NS */
5261 #else
5262 for (y = 0; y < img->height; ++y)
5263 for (x = 0; x < img->width; ++x)
5265 COLORREF p = GetPixel (ximg, x, y);
5266 if (p != bg)
5267 mask_img[y * row_width + x / 8] |= 1 << (x % 8);
5270 /* Create the mask image. */
5271 img->mask = w32_create_pixmap_from_bitmap_data (img->width, img->height,
5272 mask_img);
5273 /* Fill in the background_transparent field while we have the mask handy. */
5274 SelectObject (ximg, img->mask);
5275 image_background_transparent (img, f, ximg);
5277 /* Was: x_destroy_x_image ((XImagePtr )mask_img); which seems bogus ++kfs */
5278 xfree (mask_img);
5279 #endif /* HAVE_NTGUI */
5281 Destroy_Image (ximg, prev);
5283 return 1;
5287 /***********************************************************************
5288 PBM (mono, gray, color)
5289 ***********************************************************************/
5291 static int pbm_image_p P_ ((Lisp_Object object));
5292 static int pbm_load P_ ((struct frame *f, struct image *img));
5293 static int pbm_scan_number P_ ((unsigned char **, unsigned char *));
5295 /* The symbol `pbm' identifying images of this type. */
5297 Lisp_Object Qpbm;
5299 /* Indices of image specification fields in gs_format, below. */
5301 enum pbm_keyword_index
5303 PBM_TYPE,
5304 PBM_FILE,
5305 PBM_DATA,
5306 PBM_ASCENT,
5307 PBM_MARGIN,
5308 PBM_RELIEF,
5309 PBM_ALGORITHM,
5310 PBM_HEURISTIC_MASK,
5311 PBM_MASK,
5312 PBM_FOREGROUND,
5313 PBM_BACKGROUND,
5314 PBM_LAST
5317 /* Vector of image_keyword structures describing the format
5318 of valid user-defined image specifications. */
5320 static struct image_keyword pbm_format[PBM_LAST] =
5322 {":type", IMAGE_SYMBOL_VALUE, 1},
5323 {":file", IMAGE_STRING_VALUE, 0},
5324 {":data", IMAGE_STRING_VALUE, 0},
5325 {":ascent", IMAGE_ASCENT_VALUE, 0},
5326 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
5327 {":relief", IMAGE_INTEGER_VALUE, 0},
5328 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5329 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5330 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5331 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
5332 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
5335 /* Structure describing the image type `pbm'. */
5337 static struct image_type pbm_type =
5339 &Qpbm,
5340 pbm_image_p,
5341 pbm_load,
5342 x_clear_image,
5343 NULL
5347 /* Return non-zero if OBJECT is a valid PBM image specification. */
5349 static int
5350 pbm_image_p (object)
5351 Lisp_Object object;
5353 struct image_keyword fmt[PBM_LAST];
5355 bcopy (pbm_format, fmt, sizeof fmt);
5357 if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm))
5358 return 0;
5360 /* Must specify either :data or :file. */
5361 return fmt[PBM_DATA].count + fmt[PBM_FILE].count == 1;
5365 /* Scan a decimal number from *S and return it. Advance *S while
5366 reading the number. END is the end of the string. Value is -1 at
5367 end of input. */
5369 static int
5370 pbm_scan_number (s, end)
5371 unsigned char **s, *end;
5373 int c = 0, val = -1;
5375 while (*s < end)
5377 /* Skip white-space. */
5378 while (*s < end && (c = *(*s)++, isspace (c)))
5381 if (c == '#')
5383 /* Skip comment to end of line. */
5384 while (*s < end && (c = *(*s)++, c != '\n'))
5387 else if (isdigit (c))
5389 /* Read decimal number. */
5390 val = c - '0';
5391 while (*s < end && (c = *(*s)++, isdigit (c)))
5392 val = 10 * val + c - '0';
5393 break;
5395 else
5396 break;
5399 return val;
5403 #ifdef HAVE_NTGUI
5404 #if 0 /* Unused. ++kfs */
5406 /* Read FILE into memory. Value is a pointer to a buffer allocated
5407 with xmalloc holding FILE's contents. Value is null if an error
5408 occurred. *SIZE is set to the size of the file. */
5410 static char *
5411 pbm_read_file (file, size)
5412 Lisp_Object file;
5413 int *size;
5415 FILE *fp = NULL;
5416 char *buf = NULL;
5417 struct stat st;
5419 if (stat (SDATA (file), &st) == 0
5420 && (fp = fopen (SDATA (file), "rb")) != NULL
5421 && (buf = (char *) xmalloc (st.st_size),
5422 fread (buf, 1, st.st_size, fp) == st.st_size))
5424 *size = st.st_size;
5425 fclose (fp);
5427 else
5429 if (fp)
5430 fclose (fp);
5431 if (buf)
5433 xfree (buf);
5434 buf = NULL;
5438 return buf;
5440 #endif
5441 #endif /* HAVE_NTGUI */
5443 /* Load PBM image IMG for use on frame F. */
5445 static int
5446 pbm_load (f, img)
5447 struct frame *f;
5448 struct image *img;
5450 int raw_p, x, y;
5451 int width, height, max_color_idx = 0;
5452 XImagePtr ximg;
5453 Lisp_Object file, specified_file;
5454 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
5455 struct gcpro gcpro1;
5456 unsigned char *contents = NULL;
5457 unsigned char *end, *p;
5458 int size;
5460 specified_file = image_spec_value (img->spec, QCfile, NULL);
5461 file = Qnil;
5462 GCPRO1 (file);
5464 if (STRINGP (specified_file))
5466 file = x_find_image_file (specified_file);
5467 if (!STRINGP (file))
5469 image_error ("Cannot find image file `%s'", specified_file, Qnil);
5470 UNGCPRO;
5471 return 0;
5474 contents = slurp_file (SDATA (file), &size);
5475 if (contents == NULL)
5477 image_error ("Error reading `%s'", file, Qnil);
5478 UNGCPRO;
5479 return 0;
5482 p = contents;
5483 end = contents + size;
5485 else
5487 Lisp_Object data;
5488 data = image_spec_value (img->spec, QCdata, NULL);
5489 p = SDATA (data);
5490 end = p + SBYTES (data);
5493 /* Check magic number. */
5494 if (end - p < 2 || *p++ != 'P')
5496 image_error ("Not a PBM image: `%s'", img->spec, Qnil);
5497 error:
5498 xfree (contents);
5499 UNGCPRO;
5500 return 0;
5503 switch (*p++)
5505 case '1':
5506 raw_p = 0, type = PBM_MONO;
5507 break;
5509 case '2':
5510 raw_p = 0, type = PBM_GRAY;
5511 break;
5513 case '3':
5514 raw_p = 0, type = PBM_COLOR;
5515 break;
5517 case '4':
5518 raw_p = 1, type = PBM_MONO;
5519 break;
5521 case '5':
5522 raw_p = 1, type = PBM_GRAY;
5523 break;
5525 case '6':
5526 raw_p = 1, type = PBM_COLOR;
5527 break;
5529 default:
5530 image_error ("Not a PBM image: `%s'", img->spec, Qnil);
5531 goto error;
5534 /* Read width, height, maximum color-component. Characters
5535 starting with `#' up to the end of a line are ignored. */
5536 width = pbm_scan_number (&p, end);
5537 height = pbm_scan_number (&p, end);
5539 if (type != PBM_MONO)
5541 max_color_idx = pbm_scan_number (&p, end);
5542 if (max_color_idx > 65535 || max_color_idx < 0)
5544 image_error ("Unsupported maximum PBM color value", Qnil, Qnil);
5545 goto error;
5549 if (!check_image_size (f, width, height))
5551 image_error ("Invalid image size", Qnil, Qnil);
5552 goto error;
5555 if (!x_create_x_image_and_pixmap (f, width, height, 0,
5556 &ximg, &img->pixmap))
5557 goto error;
5559 /* Initialize the color hash table. */
5560 init_color_table ();
5562 if (type == PBM_MONO)
5564 int c = 0, g;
5565 struct image_keyword fmt[PBM_LAST];
5566 unsigned long fg = FRAME_FOREGROUND_PIXEL (f);
5567 unsigned long bg = FRAME_BACKGROUND_PIXEL (f);
5569 /* Parse the image specification. */
5570 bcopy (pbm_format, fmt, sizeof fmt);
5571 parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm);
5573 /* Get foreground and background colors, maybe allocate colors. */
5574 if (fmt[PBM_FOREGROUND].count
5575 && STRINGP (fmt[PBM_FOREGROUND].value))
5576 fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg);
5577 if (fmt[PBM_BACKGROUND].count
5578 && STRINGP (fmt[PBM_BACKGROUND].value))
5580 bg = x_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg);
5581 img->background = bg;
5582 img->background_valid = 1;
5585 for (y = 0; y < height; ++y)
5586 for (x = 0; x < width; ++x)
5588 if (raw_p)
5590 if ((x & 7) == 0)
5592 if (p >= end)
5594 x_destroy_x_image (ximg);
5595 x_clear_image (f, img);
5596 image_error ("Invalid image size in image `%s'",
5597 img->spec, Qnil);
5598 goto error;
5600 c = *p++;
5602 g = c & 0x80;
5603 c <<= 1;
5605 else
5606 g = pbm_scan_number (&p, end);
5608 XPutPixel (ximg, x, y, g ? fg : bg);
5611 else
5613 int expected_size = height * width;
5614 if (max_color_idx > 255)
5615 expected_size *= 2;
5616 if (type == PBM_COLOR)
5617 expected_size *= 3;
5619 if (raw_p && p + expected_size > end)
5621 x_destroy_x_image (ximg);
5622 x_clear_image (f, img);
5623 image_error ("Invalid image size in image `%s'",
5624 img->spec, Qnil);
5625 goto error;
5628 for (y = 0; y < height; ++y)
5629 for (x = 0; x < width; ++x)
5631 int r, g, b;
5633 if (type == PBM_GRAY && raw_p)
5635 r = g = b = *p++;
5636 if (max_color_idx > 255)
5637 r = g = b = r * 256 + *p++;
5639 else if (type == PBM_GRAY)
5640 r = g = b = pbm_scan_number (&p, end);
5641 else if (raw_p)
5643 r = *p++;
5644 if (max_color_idx > 255)
5645 r = r * 256 + *p++;
5646 g = *p++;
5647 if (max_color_idx > 255)
5648 g = g * 256 + *p++;
5649 b = *p++;
5650 if (max_color_idx > 255)
5651 b = b * 256 + *p++;
5653 else
5655 r = pbm_scan_number (&p, end);
5656 g = pbm_scan_number (&p, end);
5657 b = pbm_scan_number (&p, end);
5660 if (r < 0 || g < 0 || b < 0)
5662 x_destroy_x_image (ximg);
5663 image_error ("Invalid pixel value in image `%s'",
5664 img->spec, Qnil);
5665 goto error;
5668 /* RGB values are now in the range 0..max_color_idx.
5669 Scale this to the range 0..0xffff supported by X. */
5670 r = (double) r * 65535 / max_color_idx;
5671 g = (double) g * 65535 / max_color_idx;
5672 b = (double) b * 65535 / max_color_idx;
5673 XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
5677 #ifdef COLOR_TABLE_SUPPORT
5678 /* Store in IMG->colors the colors allocated for the image, and
5679 free the color table. */
5680 img->colors = colors_in_color_table (&img->ncolors);
5681 free_color_table ();
5682 #endif /* COLOR_TABLE_SUPPORT */
5684 img->width = width;
5685 img->height = height;
5687 /* Maybe fill in the background field while we have ximg handy. */
5689 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
5690 /* Casting avoids a GCC warning. */
5691 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
5693 /* Put the image into a pixmap. */
5694 x_put_x_image (f, ximg, img->pixmap, width, height);
5695 x_destroy_x_image (ximg);
5697 /* X and W32 versions did it here, MAC version above. ++kfs
5698 img->width = width;
5699 img->height = height; */
5701 UNGCPRO;
5702 xfree (contents);
5703 return 1;
5707 /***********************************************************************
5709 ***********************************************************************/
5711 #if defined (HAVE_PNG) || defined (HAVE_NS)
5713 /* Function prototypes. */
5715 static int png_image_p P_ ((Lisp_Object object));
5716 static int png_load P_ ((struct frame *f, struct image *img));
5718 /* The symbol `png' identifying images of this type. */
5720 Lisp_Object Qpng;
5722 /* Indices of image specification fields in png_format, below. */
5724 enum png_keyword_index
5726 PNG_TYPE,
5727 PNG_DATA,
5728 PNG_FILE,
5729 PNG_ASCENT,
5730 PNG_MARGIN,
5731 PNG_RELIEF,
5732 PNG_ALGORITHM,
5733 PNG_HEURISTIC_MASK,
5734 PNG_MASK,
5735 PNG_BACKGROUND,
5736 PNG_LAST
5739 /* Vector of image_keyword structures describing the format
5740 of valid user-defined image specifications. */
5742 static struct image_keyword png_format[PNG_LAST] =
5744 {":type", IMAGE_SYMBOL_VALUE, 1},
5745 {":data", IMAGE_STRING_VALUE, 0},
5746 {":file", IMAGE_STRING_VALUE, 0},
5747 {":ascent", IMAGE_ASCENT_VALUE, 0},
5748 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
5749 {":relief", IMAGE_INTEGER_VALUE, 0},
5750 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5751 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5752 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5753 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
5756 /* Structure describing the image type `png'. */
5758 static struct image_type png_type =
5760 &Qpng,
5761 png_image_p,
5762 png_load,
5763 x_clear_image,
5764 NULL
5767 /* Return non-zero if OBJECT is a valid PNG image specification. */
5769 static int
5770 png_image_p (object)
5771 Lisp_Object object;
5773 struct image_keyword fmt[PNG_LAST];
5774 bcopy (png_format, fmt, sizeof fmt);
5776 if (!parse_image_spec (object, fmt, PNG_LAST, Qpng))
5777 return 0;
5779 /* Must specify either the :data or :file keyword. */
5780 return fmt[PNG_FILE].count + fmt[PNG_DATA].count == 1;
5783 #endif /* HAVE_PNG || HAVE_NS */
5786 #ifdef HAVE_PNG
5788 #if defined HAVE_LIBPNG_PNG_H
5789 # include <libpng/png.h>
5790 #else
5791 # include <png.h>
5792 #endif
5794 #ifdef HAVE_NTGUI
5795 /* PNG library details. */
5797 DEF_IMGLIB_FN (png_get_io_ptr);
5798 DEF_IMGLIB_FN (png_check_sig);
5799 DEF_IMGLIB_FN (png_create_read_struct);
5800 DEF_IMGLIB_FN (png_create_info_struct);
5801 DEF_IMGLIB_FN (png_destroy_read_struct);
5802 DEF_IMGLIB_FN (png_set_read_fn);
5803 DEF_IMGLIB_FN (png_set_sig_bytes);
5804 DEF_IMGLIB_FN (png_read_info);
5805 DEF_IMGLIB_FN (png_get_IHDR);
5806 DEF_IMGLIB_FN (png_get_valid);
5807 DEF_IMGLIB_FN (png_set_strip_16);
5808 DEF_IMGLIB_FN (png_set_expand);
5809 DEF_IMGLIB_FN (png_set_gray_to_rgb);
5810 DEF_IMGLIB_FN (png_set_background);
5811 DEF_IMGLIB_FN (png_get_bKGD);
5812 DEF_IMGLIB_FN (png_read_update_info);
5813 DEF_IMGLIB_FN (png_get_channels);
5814 DEF_IMGLIB_FN (png_get_rowbytes);
5815 DEF_IMGLIB_FN (png_read_image);
5816 DEF_IMGLIB_FN (png_read_end);
5817 DEF_IMGLIB_FN (png_error);
5819 static int
5820 init_png_functions (Lisp_Object libraries)
5822 HMODULE library;
5824 /* Try loading libpng under probable names. */
5825 if (!(library = w32_delayed_load (libraries, Qpng)))
5826 return 0;
5828 LOAD_IMGLIB_FN (library, png_get_io_ptr);
5829 LOAD_IMGLIB_FN (library, png_check_sig);
5830 LOAD_IMGLIB_FN (library, png_create_read_struct);
5831 LOAD_IMGLIB_FN (library, png_create_info_struct);
5832 LOAD_IMGLIB_FN (library, png_destroy_read_struct);
5833 LOAD_IMGLIB_FN (library, png_set_read_fn);
5834 LOAD_IMGLIB_FN (library, png_set_sig_bytes);
5835 LOAD_IMGLIB_FN (library, png_read_info);
5836 LOAD_IMGLIB_FN (library, png_get_IHDR);
5837 LOAD_IMGLIB_FN (library, png_get_valid);
5838 LOAD_IMGLIB_FN (library, png_set_strip_16);
5839 LOAD_IMGLIB_FN (library, png_set_expand);
5840 LOAD_IMGLIB_FN (library, png_set_gray_to_rgb);
5841 LOAD_IMGLIB_FN (library, png_set_background);
5842 LOAD_IMGLIB_FN (library, png_get_bKGD);
5843 LOAD_IMGLIB_FN (library, png_read_update_info);
5844 LOAD_IMGLIB_FN (library, png_get_channels);
5845 LOAD_IMGLIB_FN (library, png_get_rowbytes);
5846 LOAD_IMGLIB_FN (library, png_read_image);
5847 LOAD_IMGLIB_FN (library, png_read_end);
5848 LOAD_IMGLIB_FN (library, png_error);
5849 return 1;
5851 #else
5853 #define fn_png_get_io_ptr png_get_io_ptr
5854 #define fn_png_check_sig png_check_sig
5855 #define fn_png_create_read_struct png_create_read_struct
5856 #define fn_png_create_info_struct png_create_info_struct
5857 #define fn_png_destroy_read_struct png_destroy_read_struct
5858 #define fn_png_set_read_fn png_set_read_fn
5859 #define fn_png_set_sig_bytes png_set_sig_bytes
5860 #define fn_png_read_info png_read_info
5861 #define fn_png_get_IHDR png_get_IHDR
5862 #define fn_png_get_valid png_get_valid
5863 #define fn_png_set_strip_16 png_set_strip_16
5864 #define fn_png_set_expand png_set_expand
5865 #define fn_png_set_gray_to_rgb png_set_gray_to_rgb
5866 #define fn_png_set_background png_set_background
5867 #define fn_png_get_bKGD png_get_bKGD
5868 #define fn_png_read_update_info png_read_update_info
5869 #define fn_png_get_channels png_get_channels
5870 #define fn_png_get_rowbytes png_get_rowbytes
5871 #define fn_png_read_image png_read_image
5872 #define fn_png_read_end png_read_end
5873 #define fn_png_error png_error
5875 #endif /* HAVE_NTGUI */
5877 /* Error and warning handlers installed when the PNG library
5878 is initialized. */
5880 static void
5881 my_png_error (png_ptr, msg)
5882 png_struct *png_ptr;
5883 char *msg;
5885 xassert (png_ptr != NULL);
5886 image_error ("PNG error: %s", build_string (msg), Qnil);
5887 longjmp (png_ptr->jmpbuf, 1);
5891 static void
5892 my_png_warning (png_ptr, msg)
5893 png_struct *png_ptr;
5894 char *msg;
5896 xassert (png_ptr != NULL);
5897 image_error ("PNG warning: %s", build_string (msg), Qnil);
5900 /* Memory source for PNG decoding. */
5902 struct png_memory_storage
5904 unsigned char *bytes; /* The data */
5905 size_t len; /* How big is it? */
5906 int index; /* Where are we? */
5910 /* Function set as reader function when reading PNG image from memory.
5911 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5912 bytes from the input to DATA. */
5914 static void
5915 png_read_from_memory (png_ptr, data, length)
5916 png_structp png_ptr;
5917 png_bytep data;
5918 png_size_t length;
5920 struct png_memory_storage *tbr
5921 = (struct png_memory_storage *) fn_png_get_io_ptr (png_ptr);
5923 if (length > tbr->len - tbr->index)
5924 fn_png_error (png_ptr, "Read error");
5926 bcopy (tbr->bytes + tbr->index, data, length);
5927 tbr->index = tbr->index + length;
5931 /* Function set as reader function when reading PNG image from a file.
5932 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5933 bytes from the input to DATA. */
5935 static void
5936 png_read_from_file (png_ptr, data, length)
5937 png_structp png_ptr;
5938 png_bytep data;
5939 png_size_t length;
5941 FILE *fp = (FILE *) fn_png_get_io_ptr (png_ptr);
5943 if (fread (data, 1, length, fp) < length)
5944 fn_png_error (png_ptr, "Read error");
5948 /* Load PNG image IMG for use on frame F. Value is non-zero if
5949 successful. */
5951 static int
5952 png_load (f, img)
5953 struct frame *f;
5954 struct image *img;
5956 Lisp_Object file, specified_file;
5957 Lisp_Object specified_data;
5958 int x, y, i;
5959 XImagePtr ximg, mask_img = NULL;
5960 struct gcpro gcpro1;
5961 png_struct *png_ptr = NULL;
5962 png_info *info_ptr = NULL, *end_info = NULL;
5963 FILE *volatile fp = NULL;
5964 png_byte sig[8];
5965 png_byte * volatile pixels = NULL;
5966 png_byte ** volatile rows = NULL;
5967 png_uint_32 width, height;
5968 int bit_depth, color_type, interlace_type;
5969 png_byte channels;
5970 png_uint_32 row_bytes;
5971 int transparent_p;
5972 struct png_memory_storage tbr; /* Data to be read */
5974 /* Find out what file to load. */
5975 specified_file = image_spec_value (img->spec, QCfile, NULL);
5976 specified_data = image_spec_value (img->spec, QCdata, NULL);
5977 file = Qnil;
5978 GCPRO1 (file);
5980 if (NILP (specified_data))
5982 file = x_find_image_file (specified_file);
5983 if (!STRINGP (file))
5985 image_error ("Cannot find image file `%s'", specified_file, Qnil);
5986 UNGCPRO;
5987 return 0;
5990 /* Open the image file. */
5991 fp = fopen (SDATA (file), "rb");
5992 if (!fp)
5994 image_error ("Cannot open image file `%s'", file, Qnil);
5995 UNGCPRO;
5996 return 0;
5999 /* Check PNG signature. */
6000 if (fread (sig, 1, sizeof sig, fp) != sizeof sig
6001 || !fn_png_check_sig (sig, sizeof sig))
6003 image_error ("Not a PNG file: `%s'", file, Qnil);
6004 UNGCPRO;
6005 fclose (fp);
6006 return 0;
6009 else
6011 /* Read from memory. */
6012 tbr.bytes = SDATA (specified_data);
6013 tbr.len = SBYTES (specified_data);
6014 tbr.index = 0;
6016 /* Check PNG signature. */
6017 if (tbr.len < sizeof sig
6018 || !fn_png_check_sig (tbr.bytes, sizeof sig))
6020 image_error ("Not a PNG image: `%s'", img->spec, Qnil);
6021 UNGCPRO;
6022 return 0;
6025 /* Need to skip past the signature. */
6026 tbr.bytes += sizeof (sig);
6029 /* Initialize read and info structs for PNG lib. Casting return
6030 value avoids a GCC warning on W32. */
6031 png_ptr = (png_structp)fn_png_create_read_struct (PNG_LIBPNG_VER_STRING,
6032 NULL, my_png_error,
6033 my_png_warning);
6034 if (!png_ptr)
6036 if (fp) fclose (fp);
6037 UNGCPRO;
6038 return 0;
6041 /* Casting return value avoids a GCC warning on W32. */
6042 info_ptr = (png_infop)fn_png_create_info_struct (png_ptr);
6043 if (!info_ptr)
6045 fn_png_destroy_read_struct (&png_ptr, NULL, NULL);
6046 if (fp) fclose (fp);
6047 UNGCPRO;
6048 return 0;
6051 /* Casting return value avoids a GCC warning on W32. */
6052 end_info = (png_infop)fn_png_create_info_struct (png_ptr);
6053 if (!end_info)
6055 fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
6056 if (fp) fclose (fp);
6057 UNGCPRO;
6058 return 0;
6061 /* Set error jump-back. We come back here when the PNG library
6062 detects an error. */
6063 if (setjmp (png_ptr->jmpbuf))
6065 error:
6066 if (png_ptr)
6067 fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
6068 xfree (pixels);
6069 xfree (rows);
6070 if (fp) fclose (fp);
6071 UNGCPRO;
6072 return 0;
6075 /* Read image info. */
6076 if (!NILP (specified_data))
6077 fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory);
6078 else
6079 fn_png_set_read_fn (png_ptr, (void *) fp, png_read_from_file);
6081 fn_png_set_sig_bytes (png_ptr, sizeof sig);
6082 fn_png_read_info (png_ptr, info_ptr);
6083 fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
6084 &interlace_type, NULL, NULL);
6086 if (!check_image_size (f, width, height))
6087 goto error;
6089 /* If image contains simply transparency data, we prefer to
6090 construct a clipping mask. */
6091 if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
6092 transparent_p = 1;
6093 else
6094 transparent_p = 0;
6096 /* This function is easier to write if we only have to handle
6097 one data format: RGB or RGBA with 8 bits per channel. Let's
6098 transform other formats into that format. */
6100 /* Strip more than 8 bits per channel. */
6101 if (bit_depth == 16)
6102 fn_png_set_strip_16 (png_ptr);
6104 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
6105 if available. */
6106 fn_png_set_expand (png_ptr);
6108 /* Convert grayscale images to RGB. */
6109 if (color_type == PNG_COLOR_TYPE_GRAY
6110 || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
6111 fn_png_set_gray_to_rgb (png_ptr);
6113 /* Handle alpha channel by combining the image with a background
6114 color. Do this only if a real alpha channel is supplied. For
6115 simple transparency, we prefer a clipping mask. */
6116 if (!transparent_p)
6118 /* png_color_16 *image_bg; */
6119 Lisp_Object specified_bg
6120 = image_spec_value (img->spec, QCbackground, NULL);
6121 int shift = (bit_depth == 16) ? 0 : 8;
6123 if (STRINGP (specified_bg))
6124 /* The user specified `:background', use that. */
6126 /* W32 version incorrectly used COLORREF here!! ++kfs */
6127 XColor color;
6128 if (x_defined_color (f, SDATA (specified_bg), &color, 0))
6130 png_color_16 user_bg;
6132 bzero (&user_bg, sizeof user_bg);
6133 user_bg.red = color.red >> shift;
6134 user_bg.green = color.green >> shift;
6135 user_bg.blue = color.blue >> shift;
6137 fn_png_set_background (png_ptr, &user_bg,
6138 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
6141 else
6143 /* We use the current frame background, ignoring any default
6144 background color set by the image. */
6145 #ifdef HAVE_X_WINDOWS
6146 XColor color;
6147 png_color_16 frame_background;
6149 color.pixel = FRAME_BACKGROUND_PIXEL (f);
6150 x_query_color (f, &color);
6152 bzero (&frame_background, sizeof frame_background);
6153 frame_background.red = color.red >> shift;
6154 frame_background.green = color.green >> shift;
6155 frame_background.blue = color.blue >> shift;
6156 #endif /* HAVE_X_WINDOWS */
6158 #ifdef HAVE_NTGUI
6159 COLORREF color;
6160 png_color_16 frame_background;
6161 color = FRAME_BACKGROUND_PIXEL (f);
6162 #if 0 /* W32 TODO : Colormap support. */
6163 x_query_color (f, &color);
6164 #endif
6165 bzero (&frame_background, sizeof frame_background);
6166 frame_background.red = GetRValue (color);
6167 frame_background.green = GetGValue (color);
6168 frame_background.blue = GetBValue (color);
6169 #endif /* HAVE_NTGUI */
6171 fn_png_set_background (png_ptr, &frame_background,
6172 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
6176 /* Update info structure. */
6177 fn_png_read_update_info (png_ptr, info_ptr);
6179 /* Get number of channels. Valid values are 1 for grayscale images
6180 and images with a palette, 2 for grayscale images with transparency
6181 information (alpha channel), 3 for RGB images, and 4 for RGB
6182 images with alpha channel, i.e. RGBA. If conversions above were
6183 sufficient we should only have 3 or 4 channels here. */
6184 channels = fn_png_get_channels (png_ptr, info_ptr);
6185 xassert (channels == 3 || channels == 4);
6187 /* Number of bytes needed for one row of the image. */
6188 row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr);
6190 /* Allocate memory for the image. */
6191 pixels = (png_byte *) xmalloc (row_bytes * height * sizeof *pixels);
6192 rows = (png_byte **) xmalloc (height * sizeof *rows);
6193 for (i = 0; i < height; ++i)
6194 rows[i] = pixels + i * row_bytes;
6196 /* Read the entire image. */
6197 fn_png_read_image (png_ptr, rows);
6198 fn_png_read_end (png_ptr, info_ptr);
6199 if (fp)
6201 fclose (fp);
6202 fp = NULL;
6205 /* Create the X image and pixmap. */
6206 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,
6207 &img->pixmap))
6208 goto error;
6210 /* Create an image and pixmap serving as mask if the PNG image
6211 contains an alpha channel. */
6212 if (channels == 4
6213 && !transparent_p
6214 && !x_create_x_image_and_pixmap (f, width, height, 1,
6215 &mask_img, &img->mask))
6217 x_destroy_x_image (ximg);
6218 Free_Pixmap (FRAME_X_DISPLAY (f), img->pixmap);
6219 img->pixmap = NO_PIXMAP;
6220 goto error;
6223 /* Fill the X image and mask from PNG data. */
6224 init_color_table ();
6226 for (y = 0; y < height; ++y)
6228 png_byte *p = rows[y];
6230 for (x = 0; x < width; ++x)
6232 unsigned r, g, b;
6234 r = *p++ << 8;
6235 g = *p++ << 8;
6236 b = *p++ << 8;
6237 XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
6238 /* An alpha channel, aka mask channel, associates variable
6239 transparency with an image. Where other image formats
6240 support binary transparency---fully transparent or fully
6241 opaque---PNG allows up to 254 levels of partial transparency.
6242 The PNG library implements partial transparency by combining
6243 the image with a specified background color.
6245 I'm not sure how to handle this here nicely: because the
6246 background on which the image is displayed may change, for
6247 real alpha channel support, it would be necessary to create
6248 a new image for each possible background.
6250 What I'm doing now is that a mask is created if we have
6251 boolean transparency information. Otherwise I'm using
6252 the frame's background color to combine the image with. */
6254 if (channels == 4)
6256 if (mask_img)
6257 XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN);
6258 ++p;
6263 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
6264 /* Set IMG's background color from the PNG image, unless the user
6265 overrode it. */
6267 png_color_16 *bg;
6268 if (fn_png_get_bKGD (png_ptr, info_ptr, &bg))
6270 img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue);
6271 img->background_valid = 1;
6275 #ifdef COLOR_TABLE_SUPPORT
6276 /* Remember colors allocated for this image. */
6277 img->colors = colors_in_color_table (&img->ncolors);
6278 free_color_table ();
6279 #endif /* COLOR_TABLE_SUPPORT */
6281 /* Clean up. */
6282 fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
6283 xfree (rows);
6284 xfree (pixels);
6286 img->width = width;
6287 img->height = height;
6289 /* Maybe fill in the background field while we have ximg handy.
6290 Casting avoids a GCC warning. */
6291 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
6293 /* Put the image into the pixmap, then free the X image and its buffer. */
6294 x_put_x_image (f, ximg, img->pixmap, width, height);
6295 x_destroy_x_image (ximg);
6297 /* Same for the mask. */
6298 if (mask_img)
6300 /* Fill in the background_transparent field while we have the
6301 mask handy. Casting avoids a GCC warning. */
6302 image_background_transparent (img, f, (XImagePtr_or_DC)mask_img);
6304 x_put_x_image (f, mask_img, img->mask, img->width, img->height);
6305 x_destroy_x_image (mask_img);
6308 UNGCPRO;
6309 return 1;
6312 #else /* HAVE_PNG */
6314 #ifdef HAVE_NS
6315 static int
6316 png_load (struct frame *f, struct image *img)
6318 return ns_load_image(f, img,
6319 image_spec_value (img->spec, QCfile, NULL),
6320 image_spec_value (img->spec, QCdata, NULL));
6322 #endif /* HAVE_NS */
6325 #endif /* !HAVE_PNG */
6329 /***********************************************************************
6330 JPEG
6331 ***********************************************************************/
6333 #if defined (HAVE_JPEG) || defined (HAVE_NS)
6335 static int jpeg_image_p P_ ((Lisp_Object object));
6336 static int jpeg_load P_ ((struct frame *f, struct image *img));
6338 /* The symbol `jpeg' identifying images of this type. */
6340 Lisp_Object Qjpeg;
6342 /* Indices of image specification fields in gs_format, below. */
6344 enum jpeg_keyword_index
6346 JPEG_TYPE,
6347 JPEG_DATA,
6348 JPEG_FILE,
6349 JPEG_ASCENT,
6350 JPEG_MARGIN,
6351 JPEG_RELIEF,
6352 JPEG_ALGORITHM,
6353 JPEG_HEURISTIC_MASK,
6354 JPEG_MASK,
6355 JPEG_BACKGROUND,
6356 JPEG_LAST
6359 /* Vector of image_keyword structures describing the format
6360 of valid user-defined image specifications. */
6362 static struct image_keyword jpeg_format[JPEG_LAST] =
6364 {":type", IMAGE_SYMBOL_VALUE, 1},
6365 {":data", IMAGE_STRING_VALUE, 0},
6366 {":file", IMAGE_STRING_VALUE, 0},
6367 {":ascent", IMAGE_ASCENT_VALUE, 0},
6368 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
6369 {":relief", IMAGE_INTEGER_VALUE, 0},
6370 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6371 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6372 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6373 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
6376 /* Structure describing the image type `jpeg'. */
6378 static struct image_type jpeg_type =
6380 &Qjpeg,
6381 jpeg_image_p,
6382 jpeg_load,
6383 x_clear_image,
6384 NULL
6387 /* Return non-zero if OBJECT is a valid JPEG image specification. */
6389 static int
6390 jpeg_image_p (object)
6391 Lisp_Object object;
6393 struct image_keyword fmt[JPEG_LAST];
6395 bcopy (jpeg_format, fmt, sizeof fmt);
6397 if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg))
6398 return 0;
6400 /* Must specify either the :data or :file keyword. */
6401 return fmt[JPEG_FILE].count + fmt[JPEG_DATA].count == 1;
6404 #endif /* HAVE_JPEG || HAVE_NS */
6406 #ifdef HAVE_JPEG
6408 /* Work around a warning about HAVE_STDLIB_H being redefined in
6409 jconfig.h. */
6410 #ifdef HAVE_STDLIB_H
6411 #define HAVE_STDLIB_H_1
6412 #undef HAVE_STDLIB_H
6413 #endif /* HAVE_STLIB_H */
6415 #if defined (HAVE_NTGUI) && !defined (__WIN32__)
6416 /* In older releases of the jpeg library, jpeglib.h will define boolean
6417 differently depending on __WIN32__, so make sure it is defined. */
6418 #define __WIN32__ 1
6419 #endif
6421 #include <jpeglib.h>
6422 #include <jerror.h>
6423 #include <setjmp.h>
6425 #ifdef HAVE_STLIB_H_1
6426 #define HAVE_STDLIB_H 1
6427 #endif
6429 #ifdef HAVE_NTGUI
6431 /* JPEG library details. */
6432 DEF_IMGLIB_FN (jpeg_CreateDecompress);
6433 DEF_IMGLIB_FN (jpeg_start_decompress);
6434 DEF_IMGLIB_FN (jpeg_finish_decompress);
6435 DEF_IMGLIB_FN (jpeg_destroy_decompress);
6436 DEF_IMGLIB_FN (jpeg_read_header);
6437 DEF_IMGLIB_FN (jpeg_read_scanlines);
6438 DEF_IMGLIB_FN (jpeg_std_error);
6439 DEF_IMGLIB_FN (jpeg_resync_to_restart);
6441 static int
6442 init_jpeg_functions (Lisp_Object libraries)
6444 HMODULE library;
6446 if (!(library = w32_delayed_load (libraries, Qjpeg)))
6447 return 0;
6449 LOAD_IMGLIB_FN (library, jpeg_finish_decompress);
6450 LOAD_IMGLIB_FN (library, jpeg_read_scanlines);
6451 LOAD_IMGLIB_FN (library, jpeg_start_decompress);
6452 LOAD_IMGLIB_FN (library, jpeg_read_header);
6453 LOAD_IMGLIB_FN (library, jpeg_CreateDecompress);
6454 LOAD_IMGLIB_FN (library, jpeg_destroy_decompress);
6455 LOAD_IMGLIB_FN (library, jpeg_std_error);
6456 LOAD_IMGLIB_FN (library, jpeg_resync_to_restart);
6457 return 1;
6460 /* Wrapper since we can't directly assign the function pointer
6461 to another function pointer that was declared more completely easily. */
6462 static boolean
6463 jpeg_resync_to_restart_wrapper (cinfo, desired)
6464 j_decompress_ptr cinfo;
6465 int desired;
6467 return fn_jpeg_resync_to_restart (cinfo, desired);
6470 #else
6472 #define fn_jpeg_CreateDecompress(a,b,c) jpeg_create_decompress(a)
6473 #define fn_jpeg_start_decompress jpeg_start_decompress
6474 #define fn_jpeg_finish_decompress jpeg_finish_decompress
6475 #define fn_jpeg_destroy_decompress jpeg_destroy_decompress
6476 #define fn_jpeg_read_header jpeg_read_header
6477 #define fn_jpeg_read_scanlines jpeg_read_scanlines
6478 #define fn_jpeg_std_error jpeg_std_error
6479 #define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart
6481 #endif /* HAVE_NTGUI */
6483 struct my_jpeg_error_mgr
6485 struct jpeg_error_mgr pub;
6486 jmp_buf setjmp_buffer;
6490 static void
6491 my_error_exit (cinfo)
6492 j_common_ptr cinfo;
6494 struct my_jpeg_error_mgr *mgr = (struct my_jpeg_error_mgr *) cinfo->err;
6495 longjmp (mgr->setjmp_buffer, 1);
6499 /* Init source method for JPEG data source manager. Called by
6500 jpeg_read_header() before any data is actually read. See
6501 libjpeg.doc from the JPEG lib distribution. */
6503 static void
6504 our_common_init_source (cinfo)
6505 j_decompress_ptr cinfo;
6510 /* Method to terminate data source. Called by
6511 jpeg_finish_decompress() after all data has been processed. */
6513 static void
6514 our_common_term_source (cinfo)
6515 j_decompress_ptr cinfo;
6520 /* Fill input buffer method for JPEG data source manager. Called
6521 whenever more data is needed. We read the whole image in one step,
6522 so this only adds a fake end of input marker at the end. */
6524 static JOCTET our_memory_buffer[2];
6526 static boolean
6527 our_memory_fill_input_buffer (cinfo)
6528 j_decompress_ptr cinfo;
6530 /* Insert a fake EOI marker. */
6531 struct jpeg_source_mgr *src = cinfo->src;
6533 our_memory_buffer[0] = (JOCTET) 0xFF;
6534 our_memory_buffer[1] = (JOCTET) JPEG_EOI;
6536 src->next_input_byte = our_memory_buffer;
6537 src->bytes_in_buffer = 2;
6538 return 1;
6542 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6543 is the JPEG data source manager. */
6545 static void
6546 our_memory_skip_input_data (cinfo, num_bytes)
6547 j_decompress_ptr cinfo;
6548 long num_bytes;
6550 struct jpeg_source_mgr *src = (struct jpeg_source_mgr *) cinfo->src;
6552 if (src)
6554 if (num_bytes > src->bytes_in_buffer)
6555 ERREXIT (cinfo, JERR_INPUT_EOF);
6557 src->bytes_in_buffer -= num_bytes;
6558 src->next_input_byte += num_bytes;
6563 /* Set up the JPEG lib for reading an image from DATA which contains
6564 LEN bytes. CINFO is the decompression info structure created for
6565 reading the image. */
6567 static void
6568 jpeg_memory_src (cinfo, data, len)
6569 j_decompress_ptr cinfo;
6570 JOCTET *data;
6571 unsigned int len;
6573 struct jpeg_source_mgr *src;
6575 if (cinfo->src == NULL)
6577 /* First time for this JPEG object? */
6578 cinfo->src = (struct jpeg_source_mgr *)
6579 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
6580 sizeof (struct jpeg_source_mgr));
6581 src = (struct jpeg_source_mgr *) cinfo->src;
6582 src->next_input_byte = data;
6585 src = (struct jpeg_source_mgr *) cinfo->src;
6586 src->init_source = our_common_init_source;
6587 src->fill_input_buffer = our_memory_fill_input_buffer;
6588 src->skip_input_data = our_memory_skip_input_data;
6589 src->resync_to_restart = jpeg_resync_to_restart_wrapper; /* Use default method. */
6590 src->term_source = our_common_term_source;
6591 src->bytes_in_buffer = len;
6592 src->next_input_byte = data;
6596 struct jpeg_stdio_mgr
6598 struct jpeg_source_mgr mgr;
6599 boolean finished;
6600 FILE *file;
6601 JOCTET *buffer;
6605 /* Size of buffer to read JPEG from file.
6606 Not too big, as we want to use alloc_small. */
6607 #define JPEG_STDIO_BUFFER_SIZE 8192
6610 /* Fill input buffer method for JPEG data source manager. Called
6611 whenever more data is needed. The data is read from a FILE *. */
6613 static boolean
6614 our_stdio_fill_input_buffer (cinfo)
6615 j_decompress_ptr cinfo;
6617 struct jpeg_stdio_mgr *src;
6619 src = (struct jpeg_stdio_mgr *) cinfo->src;
6620 if (!src->finished)
6622 size_t bytes;
6624 bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file);
6625 if (bytes > 0)
6626 src->mgr.bytes_in_buffer = bytes;
6627 else
6629 WARNMS (cinfo, JWRN_JPEG_EOF);
6630 src->finished = 1;
6631 src->buffer[0] = (JOCTET) 0xFF;
6632 src->buffer[1] = (JOCTET) JPEG_EOI;
6633 src->mgr.bytes_in_buffer = 2;
6635 src->mgr.next_input_byte = src->buffer;
6638 return 1;
6642 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6643 is the JPEG data source manager. */
6645 static void
6646 our_stdio_skip_input_data (cinfo, num_bytes)
6647 j_decompress_ptr cinfo;
6648 long num_bytes;
6650 struct jpeg_stdio_mgr *src;
6651 src = (struct jpeg_stdio_mgr *) cinfo->src;
6653 while (num_bytes > 0 && !src->finished)
6655 if (num_bytes <= src->mgr.bytes_in_buffer)
6657 src->mgr.bytes_in_buffer -= num_bytes;
6658 src->mgr.next_input_byte += num_bytes;
6659 break;
6661 else
6663 num_bytes -= src->mgr.bytes_in_buffer;
6664 src->mgr.bytes_in_buffer = 0;
6665 src->mgr.next_input_byte = NULL;
6667 our_stdio_fill_input_buffer (cinfo);
6673 /* Set up the JPEG lib for reading an image from a FILE *.
6674 CINFO is the decompression info structure created for
6675 reading the image. */
6677 static void
6678 jpeg_file_src (cinfo, fp)
6679 j_decompress_ptr cinfo;
6680 FILE *fp;
6682 struct jpeg_stdio_mgr *src;
6684 if (cinfo->src != NULL)
6685 src = (struct jpeg_stdio_mgr *) cinfo->src;
6686 else
6688 /* First time for this JPEG object? */
6689 cinfo->src = (struct jpeg_source_mgr *)
6690 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
6691 sizeof (struct jpeg_stdio_mgr));
6692 src = (struct jpeg_stdio_mgr *) cinfo->src;
6693 src->buffer = (JOCTET *)
6694 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
6695 JPEG_STDIO_BUFFER_SIZE);
6698 src->file = fp;
6699 src->finished = 0;
6700 src->mgr.init_source = our_common_init_source;
6701 src->mgr.fill_input_buffer = our_stdio_fill_input_buffer;
6702 src->mgr.skip_input_data = our_stdio_skip_input_data;
6703 src->mgr.resync_to_restart = jpeg_resync_to_restart_wrapper; /* Use default method. */
6704 src->mgr.term_source = our_common_term_source;
6705 src->mgr.bytes_in_buffer = 0;
6706 src->mgr.next_input_byte = NULL;
6710 /* Load image IMG for use on frame F. Patterned after example.c
6711 from the JPEG lib. */
6713 static int
6714 jpeg_load (f, img)
6715 struct frame *f;
6716 struct image *img;
6718 struct jpeg_decompress_struct cinfo;
6719 struct my_jpeg_error_mgr mgr;
6720 Lisp_Object file, specified_file;
6721 Lisp_Object specified_data;
6722 FILE * volatile fp = NULL;
6723 JSAMPARRAY buffer;
6724 int row_stride, x, y;
6725 XImagePtr ximg = NULL;
6726 int rc;
6727 unsigned long *colors;
6728 int width, height;
6729 struct gcpro gcpro1;
6731 /* Open the JPEG file. */
6732 specified_file = image_spec_value (img->spec, QCfile, NULL);
6733 specified_data = image_spec_value (img->spec, QCdata, NULL);
6734 file = Qnil;
6735 GCPRO1 (file);
6737 if (NILP (specified_data))
6739 file = x_find_image_file (specified_file);
6740 if (!STRINGP (file))
6742 image_error ("Cannot find image file `%s'", specified_file, Qnil);
6743 UNGCPRO;
6744 return 0;
6747 fp = fopen (SDATA (file), "rb");
6748 if (fp == NULL)
6750 image_error ("Cannot open `%s'", file, Qnil);
6751 UNGCPRO;
6752 return 0;
6756 /* Customize libjpeg's error handling to call my_error_exit when an
6757 error is detected. This function will perform a longjmp.
6758 Casting return value avoids a GCC warning on W32. */
6759 cinfo.err = (struct jpeg_error_mgr *)fn_jpeg_std_error (&mgr.pub);
6760 mgr.pub.error_exit = my_error_exit;
6762 if ((rc = setjmp (mgr.setjmp_buffer)) != 0)
6764 if (rc == 1)
6766 /* Called from my_error_exit. Display a JPEG error. */
6767 char buffer[JMSG_LENGTH_MAX];
6768 cinfo.err->format_message ((j_common_ptr) &cinfo, buffer);
6769 image_error ("Error reading JPEG image `%s': %s", img->spec,
6770 build_string (buffer));
6773 /* Close the input file and destroy the JPEG object. */
6774 if (fp)
6775 fclose ((FILE *) fp);
6776 fn_jpeg_destroy_decompress (&cinfo);
6778 /* If we already have an XImage, free that. */
6779 x_destroy_x_image (ximg);
6781 /* Free pixmap and colors. */
6782 x_clear_image (f, img);
6784 UNGCPRO;
6785 return 0;
6788 /* Create the JPEG decompression object. Let it read from fp.
6789 Read the JPEG image header. */
6790 fn_jpeg_CreateDecompress (&cinfo, JPEG_LIB_VERSION, sizeof (cinfo));
6792 if (NILP (specified_data))
6793 jpeg_file_src (&cinfo, (FILE *) fp);
6794 else
6795 jpeg_memory_src (&cinfo, SDATA (specified_data),
6796 SBYTES (specified_data));
6798 fn_jpeg_read_header (&cinfo, 1);
6800 /* Customize decompression so that color quantization will be used.
6801 Start decompression. */
6802 cinfo.quantize_colors = 1;
6803 fn_jpeg_start_decompress (&cinfo);
6804 width = img->width = cinfo.output_width;
6805 height = img->height = cinfo.output_height;
6807 if (!check_image_size (f, width, height))
6809 image_error ("Invalid image size", Qnil, Qnil);
6810 longjmp (mgr.setjmp_buffer, 2);
6813 /* Create X image and pixmap. */
6814 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
6815 longjmp (mgr.setjmp_buffer, 2);
6817 /* Allocate colors. When color quantization is used,
6818 cinfo.actual_number_of_colors has been set with the number of
6819 colors generated, and cinfo.colormap is a two-dimensional array
6820 of color indices in the range 0..cinfo.actual_number_of_colors.
6821 No more than 255 colors will be generated. */
6823 int i, ir, ig, ib;
6825 if (cinfo.out_color_components > 2)
6826 ir = 0, ig = 1, ib = 2;
6827 else if (cinfo.out_color_components > 1)
6828 ir = 0, ig = 1, ib = 0;
6829 else
6830 ir = 0, ig = 0, ib = 0;
6832 /* Use the color table mechanism because it handles colors that
6833 cannot be allocated nicely. Such colors will be replaced with
6834 a default color, and we don't have to care about which colors
6835 can be freed safely, and which can't. */
6836 init_color_table ();
6837 colors = (unsigned long *) alloca (cinfo.actual_number_of_colors
6838 * sizeof *colors);
6840 for (i = 0; i < cinfo.actual_number_of_colors; ++i)
6842 /* Multiply RGB values with 255 because X expects RGB values
6843 in the range 0..0xffff. */
6844 int r = cinfo.colormap[ir][i] << 8;
6845 int g = cinfo.colormap[ig][i] << 8;
6846 int b = cinfo.colormap[ib][i] << 8;
6847 colors[i] = lookup_rgb_color (f, r, g, b);
6850 #ifdef COLOR_TABLE_SUPPORT
6851 /* Remember those colors actually allocated. */
6852 img->colors = colors_in_color_table (&img->ncolors);
6853 free_color_table ();
6854 #endif /* COLOR_TABLE_SUPPORT */
6857 /* Read pixels. */
6858 row_stride = width * cinfo.output_components;
6859 buffer = cinfo.mem->alloc_sarray ((j_common_ptr) &cinfo, JPOOL_IMAGE,
6860 row_stride, 1);
6861 for (y = 0; y < height; ++y)
6863 fn_jpeg_read_scanlines (&cinfo, buffer, 1);
6864 for (x = 0; x < cinfo.output_width; ++x)
6865 XPutPixel (ximg, x, y, colors[buffer[0][x]]);
6868 /* Clean up. */
6869 fn_jpeg_finish_decompress (&cinfo);
6870 fn_jpeg_destroy_decompress (&cinfo);
6871 if (fp)
6872 fclose ((FILE *) fp);
6874 /* Maybe fill in the background field while we have ximg handy. */
6875 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
6876 /* Casting avoids a GCC warning. */
6877 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
6879 /* Put the image into the pixmap. */
6880 x_put_x_image (f, ximg, img->pixmap, width, height);
6881 x_destroy_x_image (ximg);
6882 UNGCPRO;
6883 return 1;
6886 #else /* HAVE_JPEG */
6888 #ifdef HAVE_NS
6889 static int
6890 jpeg_load (struct frame *f, struct image *img)
6892 return ns_load_image(f, img,
6893 image_spec_value (img->spec, QCfile, NULL),
6894 image_spec_value (img->spec, QCdata, NULL));
6896 #endif /* HAVE_NS */
6898 #endif /* !HAVE_JPEG */
6902 /***********************************************************************
6903 TIFF
6904 ***********************************************************************/
6906 #if defined (HAVE_TIFF) || defined (HAVE_NS)
6908 static int tiff_image_p P_ ((Lisp_Object object));
6909 static int tiff_load P_ ((struct frame *f, struct image *img));
6911 /* The symbol `tiff' identifying images of this type. */
6913 Lisp_Object Qtiff;
6915 /* Indices of image specification fields in tiff_format, below. */
6917 enum tiff_keyword_index
6919 TIFF_TYPE,
6920 TIFF_DATA,
6921 TIFF_FILE,
6922 TIFF_ASCENT,
6923 TIFF_MARGIN,
6924 TIFF_RELIEF,
6925 TIFF_ALGORITHM,
6926 TIFF_HEURISTIC_MASK,
6927 TIFF_MASK,
6928 TIFF_BACKGROUND,
6929 TIFF_INDEX,
6930 TIFF_LAST
6933 /* Vector of image_keyword structures describing the format
6934 of valid user-defined image specifications. */
6936 static struct image_keyword tiff_format[TIFF_LAST] =
6938 {":type", IMAGE_SYMBOL_VALUE, 1},
6939 {":data", IMAGE_STRING_VALUE, 0},
6940 {":file", IMAGE_STRING_VALUE, 0},
6941 {":ascent", IMAGE_ASCENT_VALUE, 0},
6942 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
6943 {":relief", IMAGE_INTEGER_VALUE, 0},
6944 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6945 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6946 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6947 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
6948 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}
6951 /* Structure describing the image type `tiff'. */
6953 static struct image_type tiff_type =
6955 &Qtiff,
6956 tiff_image_p,
6957 tiff_load,
6958 x_clear_image,
6959 NULL
6962 /* Return non-zero if OBJECT is a valid TIFF image specification. */
6964 static int
6965 tiff_image_p (object)
6966 Lisp_Object object;
6968 struct image_keyword fmt[TIFF_LAST];
6969 bcopy (tiff_format, fmt, sizeof fmt);
6971 if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff))
6972 return 0;
6974 /* Must specify either the :data or :file keyword. */
6975 return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1;
6978 #endif /* HAVE_TIFF || HAVE_NS */
6980 #ifdef HAVE_TIFF
6982 #include <tiffio.h>
6984 #ifdef HAVE_NTGUI
6986 /* TIFF library details. */
6987 DEF_IMGLIB_FN (TIFFSetErrorHandler);
6988 DEF_IMGLIB_FN (TIFFSetWarningHandler);
6989 DEF_IMGLIB_FN (TIFFOpen);
6990 DEF_IMGLIB_FN (TIFFClientOpen);
6991 DEF_IMGLIB_FN (TIFFGetField);
6992 DEF_IMGLIB_FN (TIFFReadRGBAImage);
6993 DEF_IMGLIB_FN (TIFFClose);
6994 DEF_IMGLIB_FN (TIFFSetDirectory);
6996 static int
6997 init_tiff_functions (Lisp_Object libraries)
6999 HMODULE library;
7001 if (!(library = w32_delayed_load (libraries, Qtiff)))
7002 return 0;
7004 LOAD_IMGLIB_FN (library, TIFFSetErrorHandler);
7005 LOAD_IMGLIB_FN (library, TIFFSetWarningHandler);
7006 LOAD_IMGLIB_FN (library, TIFFOpen);
7007 LOAD_IMGLIB_FN (library, TIFFClientOpen);
7008 LOAD_IMGLIB_FN (library, TIFFGetField);
7009 LOAD_IMGLIB_FN (library, TIFFReadRGBAImage);
7010 LOAD_IMGLIB_FN (library, TIFFClose);
7011 LOAD_IMGLIB_FN (library, TIFFSetDirectory);
7012 return 1;
7015 #else
7017 #define fn_TIFFSetErrorHandler TIFFSetErrorHandler
7018 #define fn_TIFFSetWarningHandler TIFFSetWarningHandler
7019 #define fn_TIFFOpen TIFFOpen
7020 #define fn_TIFFClientOpen TIFFClientOpen
7021 #define fn_TIFFGetField TIFFGetField
7022 #define fn_TIFFReadRGBAImage TIFFReadRGBAImage
7023 #define fn_TIFFClose TIFFClose
7024 #define fn_TIFFSetDirectory TIFFSetDirectory
7025 #endif /* HAVE_NTGUI */
7028 /* Reading from a memory buffer for TIFF images Based on the PNG
7029 memory source, but we have to provide a lot of extra functions.
7030 Blah.
7032 We really only need to implement read and seek, but I am not
7033 convinced that the TIFF library is smart enough not to destroy
7034 itself if we only hand it the function pointers we need to
7035 override. */
7037 typedef struct
7039 unsigned char *bytes;
7040 size_t len;
7041 int index;
7043 tiff_memory_source;
7045 static size_t
7046 tiff_read_from_memory (data, buf, size)
7047 thandle_t data;
7048 tdata_t buf;
7049 tsize_t size;
7051 tiff_memory_source *src = (tiff_memory_source *) data;
7053 if (size > src->len - src->index)
7054 return (size_t) -1;
7055 bcopy (src->bytes + src->index, buf, size);
7056 src->index += size;
7057 return size;
7060 static size_t
7061 tiff_write_from_memory (data, buf, size)
7062 thandle_t data;
7063 tdata_t buf;
7064 tsize_t size;
7066 return (size_t) -1;
7069 static toff_t
7070 tiff_seek_in_memory (data, off, whence)
7071 thandle_t data;
7072 toff_t off;
7073 int whence;
7075 tiff_memory_source *src = (tiff_memory_source *) data;
7076 int idx;
7078 switch (whence)
7080 case SEEK_SET: /* Go from beginning of source. */
7081 idx = off;
7082 break;
7084 case SEEK_END: /* Go from end of source. */
7085 idx = src->len + off;
7086 break;
7088 case SEEK_CUR: /* Go from current position. */
7089 idx = src->index + off;
7090 break;
7092 default: /* Invalid `whence'. */
7093 return -1;
7096 if (idx > src->len || idx < 0)
7097 return -1;
7099 src->index = idx;
7100 return src->index;
7103 static int
7104 tiff_close_memory (data)
7105 thandle_t data;
7107 /* NOOP */
7108 return 0;
7111 static int
7112 tiff_mmap_memory (data, pbase, psize)
7113 thandle_t data;
7114 tdata_t *pbase;
7115 toff_t *psize;
7117 /* It is already _IN_ memory. */
7118 return 0;
7121 static void
7122 tiff_unmap_memory (data, base, size)
7123 thandle_t data;
7124 tdata_t base;
7125 toff_t size;
7127 /* We don't need to do this. */
7130 static toff_t
7131 tiff_size_of_memory (data)
7132 thandle_t data;
7134 return ((tiff_memory_source *) data)->len;
7138 static void
7139 tiff_error_handler (title, format, ap)
7140 const char *title, *format;
7141 va_list ap;
7143 char buf[512];
7144 int len;
7146 len = sprintf (buf, "TIFF error: %s ", title);
7147 vsprintf (buf + len, format, ap);
7148 add_to_log (buf, Qnil, Qnil);
7152 static void
7153 tiff_warning_handler (title, format, ap)
7154 const char *title, *format;
7155 va_list ap;
7157 char buf[512];
7158 int len;
7160 len = sprintf (buf, "TIFF warning: %s ", title);
7161 vsprintf (buf + len, format, ap);
7162 add_to_log (buf, Qnil, Qnil);
7166 /* Load TIFF image IMG for use on frame F. Value is non-zero if
7167 successful. */
7169 static int
7170 tiff_load (f, img)
7171 struct frame *f;
7172 struct image *img;
7174 Lisp_Object file, specified_file;
7175 Lisp_Object specified_data;
7176 TIFF *tiff;
7177 int width, height, x, y, count;
7178 uint32 *buf;
7179 int rc, rc2;
7180 XImagePtr ximg;
7181 struct gcpro gcpro1;
7182 tiff_memory_source memsrc;
7183 Lisp_Object image;
7185 specified_file = image_spec_value (img->spec, QCfile, NULL);
7186 specified_data = image_spec_value (img->spec, QCdata, NULL);
7187 file = Qnil;
7188 GCPRO1 (file);
7190 fn_TIFFSetErrorHandler (tiff_error_handler);
7191 fn_TIFFSetWarningHandler (tiff_warning_handler);
7193 if (NILP (specified_data))
7195 /* Read from a file */
7196 file = x_find_image_file (specified_file);
7197 if (!STRINGP (file))
7199 image_error ("Cannot find image file `%s'", specified_file, Qnil);
7200 UNGCPRO;
7201 return 0;
7204 /* Try to open the image file. Casting return value avoids a
7205 GCC warning on W32. */
7206 tiff = (TIFF *)fn_TIFFOpen (SDATA (file), "r");
7207 if (tiff == NULL)
7209 image_error ("Cannot open `%s'", file, Qnil);
7210 UNGCPRO;
7211 return 0;
7214 else
7216 /* Memory source! */
7217 memsrc.bytes = SDATA (specified_data);
7218 memsrc.len = SBYTES (specified_data);
7219 memsrc.index = 0;
7221 /* Casting return value avoids a GCC warning on W32. */
7222 tiff = (TIFF *)fn_TIFFClientOpen ("memory_source", "r", &memsrc,
7223 (TIFFReadWriteProc) tiff_read_from_memory,
7224 (TIFFReadWriteProc) tiff_write_from_memory,
7225 tiff_seek_in_memory,
7226 tiff_close_memory,
7227 tiff_size_of_memory,
7228 tiff_mmap_memory,
7229 tiff_unmap_memory);
7231 if (!tiff)
7233 image_error ("Cannot open memory source for `%s'", img->spec, Qnil);
7234 UNGCPRO;
7235 return 0;
7239 image = image_spec_value (img->spec, QCindex, NULL);
7240 if (INTEGERP (image))
7242 int ino = XFASTINT (image);
7243 if (!fn_TIFFSetDirectory (tiff, ino))
7245 image_error ("Invalid image number `%s' in image `%s'",
7246 image, img->spec);
7247 fn_TIFFClose (tiff);
7248 UNGCPRO;
7249 return 0;
7253 /* Get width and height of the image, and allocate a raster buffer
7254 of width x height 32-bit values. */
7255 fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
7256 fn_TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
7258 if (!check_image_size (f, width, height))
7260 image_error ("Invalid image size", Qnil, Qnil);
7261 fn_TIFFClose (tiff);
7262 UNGCPRO;
7263 return 0;
7266 buf = (uint32 *) xmalloc (width * height * sizeof *buf);
7268 rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
7270 /* Count the number of images in the file. */
7271 for (count = 1, rc2 = 1; rc2; count++)
7272 rc2 = fn_TIFFSetDirectory (tiff, count);
7274 if (count > 1)
7275 img->data.lisp_val = Fcons (Qcount,
7276 Fcons (make_number (count),
7277 img->data.lisp_val));
7279 fn_TIFFClose (tiff);
7280 if (!rc)
7282 image_error ("Error reading TIFF image `%s'", img->spec, Qnil);
7283 xfree (buf);
7284 UNGCPRO;
7285 return 0;
7288 /* Create the X image and pixmap. */
7289 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
7291 xfree (buf);
7292 UNGCPRO;
7293 return 0;
7296 /* Initialize the color table. */
7297 init_color_table ();
7299 /* Process the pixel raster. Origin is in the lower-left corner. */
7300 for (y = 0; y < height; ++y)
7302 uint32 *row = buf + y * width;
7304 for (x = 0; x < width; ++x)
7306 uint32 abgr = row[x];
7307 int r = TIFFGetR (abgr) << 8;
7308 int g = TIFFGetG (abgr) << 8;
7309 int b = TIFFGetB (abgr) << 8;
7310 XPutPixel (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b));
7314 #ifdef COLOR_TABLE_SUPPORT
7315 /* Remember the colors allocated for the image. Free the color table. */
7316 img->colors = colors_in_color_table (&img->ncolors);
7317 free_color_table ();
7318 #endif /* COLOR_TABLE_SUPPORT */
7320 img->width = width;
7321 img->height = height;
7323 /* Maybe fill in the background field while we have ximg handy. */
7324 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7325 /* Casting avoids a GCC warning on W32. */
7326 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
7328 /* Put the image into the pixmap, then free the X image and its buffer. */
7329 x_put_x_image (f, ximg, img->pixmap, width, height);
7330 x_destroy_x_image (ximg);
7331 xfree (buf);
7333 UNGCPRO;
7334 return 1;
7337 #else /* HAVE_TIFF */
7339 #ifdef HAVE_NS
7340 static int
7341 tiff_load (struct frame *f, struct image *img)
7343 return ns_load_image(f, img,
7344 image_spec_value (img->spec, QCfile, NULL),
7345 image_spec_value (img->spec, QCdata, NULL));
7347 #endif /* HAVE_NS */
7349 #endif /* !HAVE_TIFF */
7353 /***********************************************************************
7355 ***********************************************************************/
7357 #if defined (HAVE_GIF) || defined (HAVE_NS)
7359 static int gif_image_p P_ ((Lisp_Object object));
7360 static int gif_load P_ ((struct frame *f, struct image *img));
7361 static void gif_clear_image P_ ((struct frame *f, struct image *img));
7363 /* The symbol `gif' identifying images of this type. */
7365 Lisp_Object Qgif;
7367 /* Indices of image specification fields in gif_format, below. */
7369 enum gif_keyword_index
7371 GIF_TYPE,
7372 GIF_DATA,
7373 GIF_FILE,
7374 GIF_ASCENT,
7375 GIF_MARGIN,
7376 GIF_RELIEF,
7377 GIF_ALGORITHM,
7378 GIF_HEURISTIC_MASK,
7379 GIF_MASK,
7380 GIF_IMAGE,
7381 GIF_BACKGROUND,
7382 GIF_LAST
7385 /* Vector of image_keyword structures describing the format
7386 of valid user-defined image specifications. */
7388 static struct image_keyword gif_format[GIF_LAST] =
7390 {":type", IMAGE_SYMBOL_VALUE, 1},
7391 {":data", IMAGE_STRING_VALUE, 0},
7392 {":file", IMAGE_STRING_VALUE, 0},
7393 {":ascent", IMAGE_ASCENT_VALUE, 0},
7394 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
7395 {":relief", IMAGE_INTEGER_VALUE, 0},
7396 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7397 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7398 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7399 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
7400 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
7403 /* Structure describing the image type `gif'. */
7405 static struct image_type gif_type =
7407 &Qgif,
7408 gif_image_p,
7409 gif_load,
7410 gif_clear_image,
7411 NULL
7414 /* Free X resources of GIF image IMG which is used on frame F. */
7416 static void
7417 gif_clear_image (f, img)
7418 struct frame *f;
7419 struct image *img;
7421 /* IMG->data.ptr_val may contain extension data. */
7422 img->data.lisp_val = Qnil;
7423 x_clear_image (f, img);
7426 /* Return non-zero if OBJECT is a valid GIF image specification. */
7428 static int
7429 gif_image_p (object)
7430 Lisp_Object object;
7432 struct image_keyword fmt[GIF_LAST];
7433 bcopy (gif_format, fmt, sizeof fmt);
7435 if (!parse_image_spec (object, fmt, GIF_LAST, Qgif))
7436 return 0;
7438 /* Must specify either the :data or :file keyword. */
7439 return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1;
7442 #endif /* HAVE_GIF */
7444 #ifdef HAVE_GIF
7446 #if defined (HAVE_NTGUI)
7447 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
7448 Undefine before redefining to avoid a preprocessor warning. */
7449 #ifdef DrawText
7450 #undef DrawText
7451 #endif
7452 /* avoid conflict with QuickdrawText.h */
7453 #define DrawText gif_DrawText
7454 #include <gif_lib.h>
7455 #undef DrawText
7457 #else /* HAVE_NTGUI */
7459 #include <gif_lib.h>
7461 #endif /* HAVE_NTGUI */
7464 #ifdef HAVE_NTGUI
7466 /* GIF library details. */
7467 DEF_IMGLIB_FN (DGifCloseFile);
7468 DEF_IMGLIB_FN (DGifSlurp);
7469 DEF_IMGLIB_FN (DGifOpen);
7470 DEF_IMGLIB_FN (DGifOpenFileName);
7472 static int
7473 init_gif_functions (Lisp_Object libraries)
7475 HMODULE library;
7477 if (!(library = w32_delayed_load (libraries, Qgif)))
7478 return 0;
7480 LOAD_IMGLIB_FN (library, DGifCloseFile);
7481 LOAD_IMGLIB_FN (library, DGifSlurp);
7482 LOAD_IMGLIB_FN (library, DGifOpen);
7483 LOAD_IMGLIB_FN (library, DGifOpenFileName);
7484 return 1;
7487 #else
7489 #define fn_DGifCloseFile DGifCloseFile
7490 #define fn_DGifSlurp DGifSlurp
7491 #define fn_DGifOpen DGifOpen
7492 #define fn_DGifOpenFileName DGifOpenFileName
7494 #endif /* HAVE_NTGUI */
7496 /* Reading a GIF image from memory
7497 Based on the PNG memory stuff to a certain extent. */
7499 typedef struct
7501 unsigned char *bytes;
7502 size_t len;
7503 int index;
7505 gif_memory_source;
7507 /* Make the current memory source available to gif_read_from_memory.
7508 It's done this way because not all versions of libungif support
7509 a UserData field in the GifFileType structure. */
7510 static gif_memory_source *current_gif_memory_src;
7512 static int
7513 gif_read_from_memory (file, buf, len)
7514 GifFileType *file;
7515 GifByteType *buf;
7516 int len;
7518 gif_memory_source *src = current_gif_memory_src;
7520 if (len > src->len - src->index)
7521 return -1;
7523 bcopy (src->bytes + src->index, buf, len);
7524 src->index += len;
7525 return len;
7529 /* Load GIF image IMG for use on frame F. Value is non-zero if
7530 successful. */
7532 static int interlace_start[] = {0, 4, 2, 1};
7533 static int interlace_increment[] = {8, 8, 4, 2};
7535 static int
7536 gif_load (f, img)
7537 struct frame *f;
7538 struct image *img;
7540 Lisp_Object file, specified_file;
7541 Lisp_Object specified_data;
7542 int rc, width, height, x, y, i;
7543 XImagePtr ximg;
7544 ColorMapObject *gif_color_map;
7545 unsigned long pixel_colors[256];
7546 GifFileType *gif;
7547 struct gcpro gcpro1;
7548 Lisp_Object image;
7549 int ino, image_height, image_width;
7550 gif_memory_source memsrc;
7551 unsigned char *raster;
7553 specified_file = image_spec_value (img->spec, QCfile, NULL);
7554 specified_data = image_spec_value (img->spec, QCdata, NULL);
7555 file = Qnil;
7556 GCPRO1 (file);
7558 if (NILP (specified_data))
7560 file = x_find_image_file (specified_file);
7561 if (!STRINGP (file))
7563 image_error ("Cannot find image file `%s'", specified_file, Qnil);
7564 UNGCPRO;
7565 return 0;
7568 /* Open the GIF file. Casting return value avoids a GCC warning
7569 on W32. */
7570 gif = (GifFileType *)fn_DGifOpenFileName (SDATA (file));
7571 if (gif == NULL)
7573 image_error ("Cannot open `%s'", file, Qnil);
7574 UNGCPRO;
7575 return 0;
7578 else
7580 /* Read from memory! */
7581 current_gif_memory_src = &memsrc;
7582 memsrc.bytes = SDATA (specified_data);
7583 memsrc.len = SBYTES (specified_data);
7584 memsrc.index = 0;
7586 /* Casting return value avoids a GCC warning on W32. */
7587 gif = (GifFileType *) fn_DGifOpen (&memsrc, gif_read_from_memory);
7588 if (!gif)
7590 image_error ("Cannot open memory source `%s'", img->spec, Qnil);
7591 UNGCPRO;
7592 return 0;
7596 /* Before reading entire contents, check the declared image size. */
7597 if (!check_image_size (f, gif->SWidth, gif->SHeight))
7599 image_error ("Invalid image size", Qnil, Qnil);
7600 fn_DGifCloseFile (gif);
7601 UNGCPRO;
7602 return 0;
7605 /* Read entire contents. */
7606 rc = fn_DGifSlurp (gif);
7607 if (rc == GIF_ERROR)
7609 image_error ("Error reading `%s'", img->spec, Qnil);
7610 fn_DGifCloseFile (gif);
7611 UNGCPRO;
7612 return 0;
7615 image = image_spec_value (img->spec, QCindex, NULL);
7616 ino = INTEGERP (image) ? XFASTINT (image) : 0;
7617 if (ino >= gif->ImageCount)
7619 image_error ("Invalid image number `%s' in image `%s'",
7620 image, img->spec);
7621 fn_DGifCloseFile (gif);
7622 UNGCPRO;
7623 return 0;
7626 img->corners[TOP_CORNER] = gif->SavedImages[ino].ImageDesc.Top;
7627 img->corners[LEFT_CORNER] = gif->SavedImages[ino].ImageDesc.Left;
7628 image_height = gif->SavedImages[ino].ImageDesc.Height;
7629 img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + image_height;
7630 image_width = gif->SavedImages[ino].ImageDesc.Width;
7631 img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + image_width;
7633 width = img->width = max (gif->SWidth,
7634 max (gif->Image.Left + gif->Image.Width,
7635 img->corners[RIGHT_CORNER]));
7636 height = img->height = max (gif->SHeight,
7637 max (gif->Image.Top + gif->Image.Height,
7638 img->corners[BOT_CORNER]));
7640 if (!check_image_size (f, width, height))
7642 image_error ("Invalid image size", Qnil, Qnil);
7643 fn_DGifCloseFile (gif);
7644 UNGCPRO;
7645 return 0;
7648 /* Create the X image and pixmap. */
7649 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
7651 fn_DGifCloseFile (gif);
7652 UNGCPRO;
7653 return 0;
7656 /* Allocate colors. */
7657 gif_color_map = gif->SavedImages[ino].ImageDesc.ColorMap;
7658 if (!gif_color_map)
7659 gif_color_map = gif->SColorMap;
7660 init_color_table ();
7661 bzero (pixel_colors, sizeof pixel_colors);
7663 if (gif_color_map)
7664 for (i = 0; i < gif_color_map->ColorCount; ++i)
7666 int r = gif_color_map->Colors[i].Red << 8;
7667 int g = gif_color_map->Colors[i].Green << 8;
7668 int b = gif_color_map->Colors[i].Blue << 8;
7669 pixel_colors[i] = lookup_rgb_color (f, r, g, b);
7672 #ifdef COLOR_TABLE_SUPPORT
7673 img->colors = colors_in_color_table (&img->ncolors);
7674 free_color_table ();
7675 #endif /* COLOR_TABLE_SUPPORT */
7677 /* Clear the part of the screen image that are not covered by
7678 the image from the GIF file. Full animated GIF support
7679 requires more than can be done here (see the gif89 spec,
7680 disposal methods). Let's simply assume that the part
7681 not covered by a sub-image is in the frame's background color. */
7682 for (y = 0; y < img->corners[TOP_CORNER]; ++y)
7683 for (x = 0; x < width; ++x)
7684 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7686 for (y = img->corners[BOT_CORNER]; y < height; ++y)
7687 for (x = 0; x < width; ++x)
7688 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7690 for (y = img->corners[TOP_CORNER]; y < img->corners[BOT_CORNER]; ++y)
7692 for (x = 0; x < img->corners[LEFT_CORNER]; ++x)
7693 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7694 for (x = img->corners[RIGHT_CORNER]; x < width; ++x)
7695 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7698 /* Read the GIF image into the X image. We use a local variable
7699 `raster' here because RasterBits below is a char *, and invites
7700 problems with bytes >= 0x80. */
7701 raster = (unsigned char *) gif->SavedImages[ino].RasterBits;
7703 if (gif->SavedImages[ino].ImageDesc.Interlace)
7705 int pass;
7706 int row = interlace_start[0];
7708 pass = 0;
7710 for (y = 0; y < image_height; y++)
7712 if (row >= image_height)
7714 row = interlace_start[++pass];
7715 while (row >= image_height)
7716 row = interlace_start[++pass];
7719 for (x = 0; x < image_width; x++)
7721 int i = raster[(y * image_width) + x];
7722 XPutPixel (ximg, x + img->corners[LEFT_CORNER],
7723 row + img->corners[TOP_CORNER], pixel_colors[i]);
7726 row += interlace_increment[pass];
7729 else
7731 for (y = 0; y < image_height; ++y)
7732 for (x = 0; x < image_width; ++x)
7734 int i = raster[y * image_width + x];
7735 XPutPixel (ximg, x + img->corners[LEFT_CORNER],
7736 y + img->corners[TOP_CORNER], pixel_colors[i]);
7740 /* Save GIF image extension data for `image-extension-data'.
7741 Format is (count IMAGES FUNCTION "BYTES" ...). */
7742 img->data.lisp_val = Qnil;
7743 if (gif->SavedImages[ino].ExtensionBlockCount > 0)
7745 ExtensionBlock *ext = gif->SavedImages[ino].ExtensionBlocks;
7746 for (i = 0; i < gif->SavedImages[ino].ExtensionBlockCount; i++, ext++)
7747 /* Append (... FUNCTION "BYTES") */
7748 img->data.lisp_val = Fcons (make_unibyte_string (ext->Bytes, ext->ByteCount),
7749 Fcons (make_number (ext->Function),
7750 img->data.lisp_val));
7751 img->data.lisp_val = Fnreverse (img->data.lisp_val);
7753 if (gif->ImageCount > 1)
7754 img->data.lisp_val = Fcons (Qcount,
7755 Fcons (make_number (gif->ImageCount),
7756 img->data.lisp_val));
7758 fn_DGifCloseFile (gif);
7760 /* Maybe fill in the background field while we have ximg handy. */
7761 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7762 /* Casting avoids a GCC warning. */
7763 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
7765 /* Put the image into the pixmap, then free the X image and its buffer. */
7766 x_put_x_image (f, ximg, img->pixmap, width, height);
7767 x_destroy_x_image (ximg);
7769 UNGCPRO;
7770 return 1;
7773 #else /* !HAVE_GIF */
7775 #ifdef HAVE_NS
7776 static int
7777 gif_load (struct frame *f, struct image *img)
7779 return ns_load_image(f, img,
7780 image_spec_value (img->spec, QCfile, NULL),
7781 image_spec_value (img->spec, QCdata, NULL));
7783 #endif /* HAVE_NS */
7785 #endif /* HAVE_GIF */
7789 /***********************************************************************
7791 ***********************************************************************/
7793 #if defined (HAVE_RSVG)
7795 /* Function prototypes. */
7797 static int svg_image_p P_ ((Lisp_Object object));
7798 static int svg_load P_ ((struct frame *f, struct image *img));
7800 static int svg_load_image P_ ((struct frame *, struct image *,
7801 unsigned char *, unsigned int));
7803 /* The symbol `svg' identifying images of this type. */
7805 Lisp_Object Qsvg;
7807 /* Indices of image specification fields in svg_format, below. */
7809 enum svg_keyword_index
7811 SVG_TYPE,
7812 SVG_DATA,
7813 SVG_FILE,
7814 SVG_ASCENT,
7815 SVG_MARGIN,
7816 SVG_RELIEF,
7817 SVG_ALGORITHM,
7818 SVG_HEURISTIC_MASK,
7819 SVG_MASK,
7820 SVG_BACKGROUND,
7821 SVG_LAST
7824 /* Vector of image_keyword structures describing the format
7825 of valid user-defined image specifications. */
7827 static struct image_keyword svg_format[SVG_LAST] =
7829 {":type", IMAGE_SYMBOL_VALUE, 1},
7830 {":data", IMAGE_STRING_VALUE, 0},
7831 {":file", IMAGE_STRING_VALUE, 0},
7832 {":ascent", IMAGE_ASCENT_VALUE, 0},
7833 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
7834 {":relief", IMAGE_INTEGER_VALUE, 0},
7835 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7836 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7837 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7838 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
7841 /* Structure describing the image type `svg'. Its the same type of
7842 structure defined for all image formats, handled by emacs image
7843 functions. See struct image_type in dispextern.h. */
7845 static struct image_type svg_type =
7847 /* An identifier showing that this is an image structure for the SVG format. */
7848 &Qsvg,
7849 /* Handle to a function that can be used to identify a SVG file. */
7850 svg_image_p,
7851 /* Handle to function used to load a SVG file. */
7852 svg_load,
7853 /* Handle to function to free sresources for SVG. */
7854 x_clear_image,
7855 /* An internal field to link to the next image type in a list of
7856 image types, will be filled in when registering the format. */
7857 NULL
7861 /* Return non-zero if OBJECT is a valid SVG image specification. Do
7862 this by calling parse_image_spec and supplying the keywords that
7863 identify the SVG format. */
7865 static int
7866 svg_image_p (object)
7867 Lisp_Object object;
7869 struct image_keyword fmt[SVG_LAST];
7870 bcopy (svg_format, fmt, sizeof fmt);
7872 if (!parse_image_spec (object, fmt, SVG_LAST, Qsvg))
7873 return 0;
7875 /* Must specify either the :data or :file keyword. */
7876 return fmt[SVG_FILE].count + fmt[SVG_DATA].count == 1;
7879 #include <librsvg/rsvg.h>
7881 #ifdef HAVE_NTGUI
7883 /* SVG library functions. */
7884 DEF_IMGLIB_FN (rsvg_handle_new);
7885 DEF_IMGLIB_FN (rsvg_handle_get_dimensions);
7886 DEF_IMGLIB_FN (rsvg_handle_write);
7887 DEF_IMGLIB_FN (rsvg_handle_close);
7888 DEF_IMGLIB_FN (rsvg_handle_get_pixbuf);
7889 DEF_IMGLIB_FN (rsvg_handle_free);
7891 DEF_IMGLIB_FN (gdk_pixbuf_get_width);
7892 DEF_IMGLIB_FN (gdk_pixbuf_get_height);
7893 DEF_IMGLIB_FN (gdk_pixbuf_get_pixels);
7894 DEF_IMGLIB_FN (gdk_pixbuf_get_rowstride);
7895 DEF_IMGLIB_FN (gdk_pixbuf_get_colorspace);
7896 DEF_IMGLIB_FN (gdk_pixbuf_get_n_channels);
7897 DEF_IMGLIB_FN (gdk_pixbuf_get_has_alpha);
7898 DEF_IMGLIB_FN (gdk_pixbuf_get_bits_per_sample);
7900 DEF_IMGLIB_FN (g_type_init);
7901 DEF_IMGLIB_FN (g_object_unref);
7902 DEF_IMGLIB_FN (g_error_free);
7904 Lisp_Object Qgdk_pixbuf, Qglib;
7906 static int
7907 init_svg_functions (Lisp_Object libraries)
7909 HMODULE library, gdklib, glib;
7911 if (!(glib = w32_delayed_load (libraries, Qglib))
7912 || !(gdklib = w32_delayed_load (libraries, Qgdk_pixbuf))
7913 || !(library = w32_delayed_load (libraries, Qsvg)))
7914 return 0;
7916 LOAD_IMGLIB_FN (library, rsvg_handle_new);
7917 LOAD_IMGLIB_FN (library, rsvg_handle_get_dimensions);
7918 LOAD_IMGLIB_FN (library, rsvg_handle_write);
7919 LOAD_IMGLIB_FN (library, rsvg_handle_close);
7920 LOAD_IMGLIB_FN (library, rsvg_handle_get_pixbuf);
7921 LOAD_IMGLIB_FN (library, rsvg_handle_free);
7923 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_width);
7924 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_height);
7925 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_pixels);
7926 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_rowstride);
7927 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_colorspace);
7928 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_n_channels);
7929 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_has_alpha);
7930 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_bits_per_sample);
7932 LOAD_IMGLIB_FN (glib, g_type_init);
7933 LOAD_IMGLIB_FN (glib, g_object_unref);
7934 LOAD_IMGLIB_FN (glib, g_error_free);
7935 return 1;
7938 #else
7939 /* The following aliases for library functions allow dynamic loading
7940 to be used on some platforms. */
7941 #define fn_rsvg_handle_new rsvg_handle_new
7942 #define fn_rsvg_handle_get_dimensions rsvg_handle_get_dimensions
7943 #define fn_rsvg_handle_write rsvg_handle_write
7944 #define fn_rsvg_handle_close rsvg_handle_close
7945 #define fn_rsvg_handle_get_pixbuf rsvg_handle_get_pixbuf
7946 #define fn_rsvg_handle_free rsvg_handle_free
7948 #define fn_gdk_pixbuf_get_width gdk_pixbuf_get_width
7949 #define fn_gdk_pixbuf_get_height gdk_pixbuf_get_height
7950 #define fn_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels
7951 #define fn_gdk_pixbuf_get_rowstride gdk_pixbuf_get_rowstride
7952 #define fn_gdk_pixbuf_get_colorspace gdk_pixbuf_get_colorspace
7953 #define fn_gdk_pixbuf_get_n_channels gdk_pixbuf_get_n_channels
7954 #define fn_gdk_pixbuf_get_has_alpha gdk_pixbuf_get_has_alpha
7955 #define fn_gdk_pixbuf_get_bits_per_sample gdk_pixbuf_get_bits_per_sample
7957 #define fn_g_type_init g_type_init
7958 #define fn_g_object_unref g_object_unref
7959 #define fn_g_error_free g_error_free
7960 #endif /* !HAVE_NTGUI */
7962 /* Load SVG image IMG for use on frame F. Value is non-zero if
7963 successful. this function will go into the svg_type structure, and
7964 the prototype thus needs to be compatible with that structure. */
7966 static int
7967 svg_load (f, img)
7968 struct frame *f;
7969 struct image *img;
7971 int success_p = 0;
7972 Lisp_Object file_name;
7974 /* If IMG->spec specifies a file name, create a non-file spec from it. */
7975 file_name = image_spec_value (img->spec, QCfile, NULL);
7976 if (STRINGP (file_name))
7978 Lisp_Object file;
7979 unsigned char *contents;
7980 int size;
7981 struct gcpro gcpro1;
7983 file = x_find_image_file (file_name);
7984 GCPRO1 (file);
7985 if (!STRINGP (file))
7987 image_error ("Cannot find image file `%s'", file_name, Qnil);
7988 UNGCPRO;
7989 return 0;
7992 /* Read the entire file into memory. */
7993 contents = slurp_file (SDATA (file), &size);
7994 if (contents == NULL)
7996 image_error ("Error loading SVG image `%s'", img->spec, Qnil);
7997 UNGCPRO;
7998 return 0;
8000 /* If the file was slurped into memory properly, parse it. */
8001 success_p = svg_load_image (f, img, contents, size);
8002 xfree (contents);
8003 UNGCPRO;
8005 /* Else its not a file, its a lisp object. Load the image from a
8006 lisp object rather than a file. */
8007 else
8009 Lisp_Object data;
8011 data = image_spec_value (img->spec, QCdata, NULL);
8012 success_p = svg_load_image (f, img, SDATA (data), SBYTES (data));
8015 return success_p;
8018 /* svg_load_image is a helper function for svg_load, which does the
8019 actual loading given contents and size, apart from frame and image
8020 structures, passed from svg_load.
8022 Uses librsvg to do most of the image processing.
8024 Returns non-zero when successful. */
8025 static int
8026 svg_load_image (f, img, contents, size)
8027 /* Pointer to emacs frame structure. */
8028 struct frame *f;
8029 /* Pointer to emacs image structure. */
8030 struct image *img;
8031 /* String containing the SVG XML data to be parsed. */
8032 unsigned char *contents;
8033 /* Size of data in bytes. */
8034 unsigned int size;
8036 RsvgHandle *rsvg_handle;
8037 RsvgDimensionData dimension_data;
8038 GError *error = NULL;
8039 GdkPixbuf *pixbuf;
8040 int width;
8041 int height;
8042 const guint8 *pixels;
8043 int rowstride;
8044 XImagePtr ximg;
8045 Lisp_Object specified_bg;
8046 XColor background;
8047 int x;
8048 int y;
8050 /* g_type_init is a glib function that must be called prior to using
8051 gnome type library functions. */
8052 fn_g_type_init ();
8053 /* Make a handle to a new rsvg object. */
8054 rsvg_handle = fn_rsvg_handle_new ();
8056 /* Parse the contents argument and fill in the rsvg_handle. */
8057 fn_rsvg_handle_write (rsvg_handle, contents, size, &error);
8058 if (error) goto rsvg_error;
8060 /* The parsing is complete, rsvg_handle is ready to used, close it
8061 for further writes. */
8062 fn_rsvg_handle_close (rsvg_handle, &error);
8063 if (error) goto rsvg_error;
8065 fn_rsvg_handle_get_dimensions (rsvg_handle, &dimension_data);
8066 if (! check_image_size (f, dimension_data.width, dimension_data.height))
8067 goto rsvg_error;
8069 /* We can now get a valid pixel buffer from the svg file, if all
8070 went ok. */
8071 pixbuf = fn_rsvg_handle_get_pixbuf (rsvg_handle);
8072 if (!pixbuf) goto rsvg_error;
8073 fn_g_object_unref (rsvg_handle);
8075 /* Extract some meta data from the svg handle. */
8076 width = fn_gdk_pixbuf_get_width (pixbuf);
8077 height = fn_gdk_pixbuf_get_height (pixbuf);
8078 pixels = fn_gdk_pixbuf_get_pixels (pixbuf);
8079 rowstride = fn_gdk_pixbuf_get_rowstride (pixbuf);
8081 /* Validate the svg meta data. */
8082 eassert (fn_gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB);
8083 eassert (fn_gdk_pixbuf_get_n_channels (pixbuf) == 4);
8084 eassert (fn_gdk_pixbuf_get_has_alpha (pixbuf));
8085 eassert (fn_gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
8087 /* Try to create a x pixmap to hold the svg pixmap. */
8088 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
8090 fn_g_object_unref (pixbuf);
8091 return 0;
8094 init_color_table ();
8096 /* Handle alpha channel by combining the image with a background
8097 color. */
8098 specified_bg = image_spec_value (img->spec, QCbackground, NULL);
8099 if (STRINGP (specified_bg)
8100 && x_defined_color (f, SDATA (specified_bg), &background, 0))
8102 background.red >>= 8;
8103 background.green >>= 8;
8104 background.blue >>= 8;
8106 else
8108 #ifdef HAVE_X_WINDOWS
8109 background.pixel = FRAME_BACKGROUND_PIXEL (f);
8110 x_query_color (f, &background);
8112 /* SVG pixmaps specify transparency in the last byte, so right
8113 shift 8 bits to get rid of it, since emacs doesn't support
8114 transparency. */
8115 background.red >>= 8;
8116 background.green >>= 8;
8117 background.blue >>= 8;
8118 #elif defined (HAVE_NTGUI)
8119 background.pixel = FRAME_BACKGROUND_PIXEL (f);
8120 #if 0 /* W32 TODO : Colormap support. */
8121 x_query_color (f, &background);
8122 #endif
8124 /* SVG pixmaps specify transparency in the last byte, so right
8125 shift 8 bits to get rid of it, since emacs doesn't support
8126 transparency. */
8127 background.red >>= 8;
8128 background.green >>= 8;
8129 background.blue >>= 8;
8130 #else /* not HAVE_X_WINDOWS*/
8131 #error FIXME
8132 #endif
8135 /* This loop handles opacity values, since Emacs assumes
8136 non-transparent images. Each pixel must be "flattened" by
8137 calculating the resulting color, given the transparency of the
8138 pixel, and the image background color. */
8139 for (y = 0; y < height; ++y)
8141 for (x = 0; x < width; ++x)
8143 unsigned red;
8144 unsigned green;
8145 unsigned blue;
8146 unsigned opacity;
8148 red = *pixels++;
8149 green = *pixels++;
8150 blue = *pixels++;
8151 opacity = *pixels++;
8153 red = ((red * opacity)
8154 + (background.red * ((1 << 8) - opacity)));
8155 green = ((green * opacity)
8156 + (background.green * ((1 << 8) - opacity)));
8157 blue = ((blue * opacity)
8158 + (background.blue * ((1 << 8) - opacity)));
8160 XPutPixel (ximg, x, y, lookup_rgb_color (f, red, green, blue));
8163 pixels += rowstride - 4 * width;
8166 #ifdef COLOR_TABLE_SUPPORT
8167 /* Remember colors allocated for this image. */
8168 img->colors = colors_in_color_table (&img->ncolors);
8169 free_color_table ();
8170 #endif /* COLOR_TABLE_SUPPORT */
8172 fn_g_object_unref (pixbuf);
8174 img->width = width;
8175 img->height = height;
8177 /* Maybe fill in the background field while we have ximg handy.
8178 Casting avoids a GCC warning. */
8179 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
8181 /* Put the image into the pixmap, then free the X image and its
8182 buffer. */
8183 x_put_x_image (f, ximg, img->pixmap, width, height);
8184 x_destroy_x_image (ximg);
8186 return 1;
8188 rsvg_error:
8189 fn_g_object_unref (rsvg_handle);
8190 /* FIXME: Use error->message so the user knows what is the actual
8191 problem with the image. */
8192 image_error ("Error parsing SVG image `%s'", img->spec, Qnil);
8193 fn_g_error_free (error);
8194 return 0;
8197 #endif /* defined (HAVE_RSVG) */
8202 /***********************************************************************
8203 Ghostscript
8204 ***********************************************************************/
8206 #ifdef HAVE_X_WINDOWS
8207 #define HAVE_GHOSTSCRIPT 1
8208 #endif /* HAVE_X_WINDOWS */
8210 /* The symbol `postscript' identifying images of this type. */
8212 Lisp_Object Qpostscript;
8214 #ifdef HAVE_GHOSTSCRIPT
8216 static int gs_image_p P_ ((Lisp_Object object));
8217 static int gs_load P_ ((struct frame *f, struct image *img));
8218 static void gs_clear_image P_ ((struct frame *f, struct image *img));
8220 /* Keyword symbols. */
8222 Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height;
8224 /* Indices of image specification fields in gs_format, below. */
8226 enum gs_keyword_index
8228 GS_TYPE,
8229 GS_PT_WIDTH,
8230 GS_PT_HEIGHT,
8231 GS_FILE,
8232 GS_LOADER,
8233 GS_BOUNDING_BOX,
8234 GS_ASCENT,
8235 GS_MARGIN,
8236 GS_RELIEF,
8237 GS_ALGORITHM,
8238 GS_HEURISTIC_MASK,
8239 GS_MASK,
8240 GS_BACKGROUND,
8241 GS_LAST
8244 /* Vector of image_keyword structures describing the format
8245 of valid user-defined image specifications. */
8247 static struct image_keyword gs_format[GS_LAST] =
8249 {":type", IMAGE_SYMBOL_VALUE, 1},
8250 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE, 1},
8251 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE, 1},
8252 {":file", IMAGE_STRING_VALUE, 1},
8253 {":loader", IMAGE_FUNCTION_VALUE, 0},
8254 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1},
8255 {":ascent", IMAGE_ASCENT_VALUE, 0},
8256 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
8257 {":relief", IMAGE_INTEGER_VALUE, 0},
8258 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8259 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8260 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8261 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
8264 /* Structure describing the image type `ghostscript'. */
8266 static struct image_type gs_type =
8268 &Qpostscript,
8269 gs_image_p,
8270 gs_load,
8271 gs_clear_image,
8272 NULL
8276 /* Free X resources of Ghostscript image IMG which is used on frame F. */
8278 static void
8279 gs_clear_image (f, img)
8280 struct frame *f;
8281 struct image *img;
8283 /* IMG->data.ptr_val may contain a recorded colormap. */
8284 xfree (img->data.ptr_val);
8285 x_clear_image (f, img);
8289 /* Return non-zero if OBJECT is a valid Ghostscript image
8290 specification. */
8292 static int
8293 gs_image_p (object)
8294 Lisp_Object object;
8296 struct image_keyword fmt[GS_LAST];
8297 Lisp_Object tem;
8298 int i;
8300 bcopy (gs_format, fmt, sizeof fmt);
8302 if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript))
8303 return 0;
8305 /* Bounding box must be a list or vector containing 4 integers. */
8306 tem = fmt[GS_BOUNDING_BOX].value;
8307 if (CONSP (tem))
8309 for (i = 0; i < 4; ++i, tem = XCDR (tem))
8310 if (!CONSP (tem) || !INTEGERP (XCAR (tem)))
8311 return 0;
8312 if (!NILP (tem))
8313 return 0;
8315 else if (VECTORP (tem))
8317 if (XVECTOR (tem)->size != 4)
8318 return 0;
8319 for (i = 0; i < 4; ++i)
8320 if (!INTEGERP (XVECTOR (tem)->contents[i]))
8321 return 0;
8323 else
8324 return 0;
8326 return 1;
8330 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
8331 if successful. */
8333 static int
8334 gs_load (f, img)
8335 struct frame *f;
8336 struct image *img;
8338 char buffer[100];
8339 Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width;
8340 struct gcpro gcpro1, gcpro2;
8341 Lisp_Object frame;
8342 double in_width, in_height;
8343 Lisp_Object pixel_colors = Qnil;
8345 /* Compute pixel size of pixmap needed from the given size in the
8346 image specification. Sizes in the specification are in pt. 1 pt
8347 = 1/72 in, xdpi and ydpi are stored in the frame's X display
8348 info. */
8349 pt_width = image_spec_value (img->spec, QCpt_width, NULL);
8350 in_width = XFASTINT (pt_width) / 72.0;
8351 img->width = in_width * FRAME_X_DISPLAY_INFO (f)->resx;
8352 pt_height = image_spec_value (img->spec, QCpt_height, NULL);
8353 in_height = XFASTINT (pt_height) / 72.0;
8354 img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy;
8356 if (!check_image_size (f, img->width, img->height))
8358 image_error ("Invalid image size", Qnil, Qnil);
8359 return 0;
8362 /* Create the pixmap. */
8363 xassert (img->pixmap == NO_PIXMAP);
8365 /* Only W32 version did BLOCK_INPUT here. ++kfs */
8366 BLOCK_INPUT;
8367 img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
8368 img->width, img->height,
8369 DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
8370 UNBLOCK_INPUT;
8372 if (!img->pixmap)
8374 image_error ("Unable to create pixmap for `%s'", img->spec, Qnil);
8375 return 0;
8378 /* Call the loader to fill the pixmap. It returns a process object
8379 if successful. We do not record_unwind_protect here because
8380 other places in redisplay like calling window scroll functions
8381 don't either. Let the Lisp loader use `unwind-protect' instead. */
8382 GCPRO2 (window_and_pixmap_id, pixel_colors);
8384 sprintf (buffer, "%lu %lu",
8385 (unsigned long) FRAME_X_WINDOW (f),
8386 (unsigned long) img->pixmap);
8387 window_and_pixmap_id = build_string (buffer);
8389 sprintf (buffer, "%lu %lu",
8390 FRAME_FOREGROUND_PIXEL (f),
8391 FRAME_BACKGROUND_PIXEL (f));
8392 pixel_colors = build_string (buffer);
8394 XSETFRAME (frame, f);
8395 loader = image_spec_value (img->spec, QCloader, NULL);
8396 if (NILP (loader))
8397 loader = intern ("gs-load-image");
8399 img->data.lisp_val = call6 (loader, frame, img->spec,
8400 make_number (img->width),
8401 make_number (img->height),
8402 window_and_pixmap_id,
8403 pixel_colors);
8404 UNGCPRO;
8405 return PROCESSP (img->data.lisp_val);
8409 /* Kill the Ghostscript process that was started to fill PIXMAP on
8410 frame F. Called from XTread_socket when receiving an event
8411 telling Emacs that Ghostscript has finished drawing. */
8413 void
8414 x_kill_gs_process (pixmap, f)
8415 Pixmap pixmap;
8416 struct frame *f;
8418 struct image_cache *c = FRAME_IMAGE_CACHE (f);
8419 int class, i;
8420 struct image *img;
8422 /* Find the image containing PIXMAP. */
8423 for (i = 0; i < c->used; ++i)
8424 if (c->images[i]->pixmap == pixmap)
8425 break;
8427 /* Should someone in between have cleared the image cache, for
8428 instance, give up. */
8429 if (i == c->used)
8430 return;
8432 /* Kill the GS process. We should have found PIXMAP in the image
8433 cache and its image should contain a process object. */
8434 img = c->images[i];
8435 xassert (PROCESSP (img->data.lisp_val));
8436 Fkill_process (img->data.lisp_val, Qnil);
8437 img->data.lisp_val = Qnil;
8439 #if defined (HAVE_X_WINDOWS)
8441 /* On displays with a mutable colormap, figure out the colors
8442 allocated for the image by looking at the pixels of an XImage for
8443 img->pixmap. */
8444 class = FRAME_X_VISUAL (f)->class;
8445 if (class != StaticColor && class != StaticGray && class != TrueColor)
8447 XImagePtr ximg;
8449 BLOCK_INPUT;
8451 /* Try to get an XImage for img->pixmep. */
8452 ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
8453 0, 0, img->width, img->height, ~0, ZPixmap);
8454 if (ximg)
8456 int x, y;
8458 /* Initialize the color table. */
8459 init_color_table ();
8461 /* For each pixel of the image, look its color up in the
8462 color table. After having done so, the color table will
8463 contain an entry for each color used by the image. */
8464 for (y = 0; y < img->height; ++y)
8465 for (x = 0; x < img->width; ++x)
8467 unsigned long pixel = XGetPixel (ximg, x, y);
8468 lookup_pixel_color (f, pixel);
8471 /* Record colors in the image. Free color table and XImage. */
8472 #ifdef COLOR_TABLE_SUPPORT
8473 img->colors = colors_in_color_table (&img->ncolors);
8474 free_color_table ();
8475 #endif
8476 XDestroyImage (ximg);
8478 #if 0 /* This doesn't seem to be the case. If we free the colors
8479 here, we get a BadAccess later in x_clear_image when
8480 freeing the colors. */
8481 /* We have allocated colors once, but Ghostscript has also
8482 allocated colors on behalf of us. So, to get the
8483 reference counts right, free them once. */
8484 if (img->ncolors)
8485 x_free_colors (f, img->colors, img->ncolors);
8486 #endif
8488 else
8489 image_error ("Cannot get X image of `%s'; colors will not be freed",
8490 img->spec, Qnil);
8492 UNBLOCK_INPUT;
8494 #endif /* HAVE_X_WINDOWS */
8496 /* Now that we have the pixmap, compute mask and transform the
8497 image if requested. */
8498 BLOCK_INPUT;
8499 postprocess_image (f, img);
8500 UNBLOCK_INPUT;
8503 #endif /* HAVE_GHOSTSCRIPT */
8506 /***********************************************************************
8507 Tests
8508 ***********************************************************************/
8510 #if GLYPH_DEBUG
8512 DEFUN ("imagep", Fimagep, Simagep, 1, 1, 0,
8513 doc: /* Value is non-nil if SPEC is a valid image specification. */)
8514 (spec)
8515 Lisp_Object spec;
8517 return valid_image_p (spec) ? Qt : Qnil;
8521 DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
8522 (spec)
8523 Lisp_Object spec;
8525 int id = -1;
8527 if (valid_image_p (spec))
8528 id = lookup_image (SELECTED_FRAME (), spec);
8530 debug_print (spec);
8531 return make_number (id);
8534 #endif /* GLYPH_DEBUG != 0 */
8537 /***********************************************************************
8538 Initialization
8539 ***********************************************************************/
8541 #ifdef HAVE_NTGUI
8542 /* Image types that rely on external libraries are loaded dynamically
8543 if the library is available. */
8544 #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8545 define_image_type (image_type, init_lib_fn (libraries))
8546 #else
8547 #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8548 define_image_type (image_type, 1)
8549 #endif /* HAVE_NTGUI */
8551 DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2, 2, 0,
8552 doc: /* Initialize image library implementing image type TYPE.
8553 Return non-nil if TYPE is a supported image type.
8555 Image types pbm and xbm are prebuilt; other types are loaded here.
8556 Libraries to load are specified in alist LIBRARIES (usually, the value
8557 of `image-library-alist', which see). */)
8558 (type, libraries)
8559 Lisp_Object type, libraries;
8561 Lisp_Object tested;
8563 /* Don't try to reload the library. */
8564 tested = Fassq (type, Vimage_type_cache);
8565 if (CONSP (tested))
8566 return XCDR (tested);
8568 #if defined (HAVE_XPM) || defined (HAVE_NS)
8569 if (EQ (type, Qxpm))
8570 return CHECK_LIB_AVAILABLE (&xpm_type, init_xpm_functions, libraries);
8571 #endif
8573 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8574 if (EQ (type, Qjpeg))
8575 return CHECK_LIB_AVAILABLE (&jpeg_type, init_jpeg_functions, libraries);
8576 #endif
8578 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8579 if (EQ (type, Qtiff))
8580 return CHECK_LIB_AVAILABLE (&tiff_type, init_tiff_functions, libraries);
8581 #endif
8583 #if defined (HAVE_GIF) || defined (HAVE_NS)
8584 if (EQ (type, Qgif))
8585 return CHECK_LIB_AVAILABLE (&gif_type, init_gif_functions, libraries);
8586 #endif
8588 #if defined (HAVE_PNG) || defined (HAVE_NS)
8589 if (EQ (type, Qpng))
8590 return CHECK_LIB_AVAILABLE (&png_type, init_png_functions, libraries);
8591 #endif
8593 #if defined (HAVE_RSVG)
8594 if (EQ (type, Qsvg))
8595 return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries);
8596 #endif
8598 #ifdef HAVE_GHOSTSCRIPT
8599 if (EQ (type, Qpostscript))
8600 return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries);
8601 #endif
8603 /* If the type is not recognized, avoid testing it ever again. */
8604 CACHE_IMAGE_TYPE (type, Qnil);
8605 return Qnil;
8608 void
8609 syms_of_image ()
8611 extern Lisp_Object Qrisky_local_variable; /* Syms_of_xdisp has already run. */
8613 /* Initialize this only once, since that's what we do with Vimage_types
8614 and they are supposed to be in sync. Initializing here gives correct
8615 operation on GNU/Linux of calling dump-emacs after loading some images. */
8616 image_types = NULL;
8618 /* Must be defined now becase we're going to update it below, while
8619 defining the supported image types. */
8620 DEFVAR_LISP ("image-types", &Vimage_types,
8621 doc: /* List of potentially supported image types.
8622 Each element of the list is a symbol for an image type, like 'jpeg or 'png.
8623 To check whether it is really supported, use `image-type-available-p'. */);
8624 Vimage_types = Qnil;
8626 DEFVAR_LISP ("image-library-alist", &Vimage_library_alist,
8627 doc: /* Alist of image types vs external libraries needed to display them.
8629 Each element is a list (IMAGE-TYPE LIBRARY...), where the car is a symbol
8630 representing a supported image type, and the rest are strings giving
8631 alternate filenames for the corresponding external libraries.
8633 Emacs tries to load the libraries in the order they appear on the
8634 list; if none is loaded, the running session of Emacs won't
8635 support the image type. Types 'pbm and 'xbm don't need to be
8636 listed; they are always supported. */);
8637 Vimage_library_alist = Qnil;
8638 Fput (intern ("image-library-alist"), Qrisky_local_variable, Qt);
8640 DEFVAR_LISP ("max-image-size", &Vmax_image_size,
8641 doc: /* Maximum size of images.
8642 Emacs will not load an image into memory if its pixel width or
8643 pixel height exceeds this limit.
8645 If the value is an integer, it directly specifies the maximum
8646 image height and width, measured in pixels. If it is a floating
8647 point number, it specifies the maximum image height and width
8648 as a ratio to the frame height and width. If the value is
8649 non-numeric, there is no explicit limit on the size of images. */);
8650 Vmax_image_size = make_float (MAX_IMAGE_SIZE);
8652 Vimage_type_cache = Qnil;
8653 staticpro (&Vimage_type_cache);
8655 Qpbm = intern ("pbm");
8656 staticpro (&Qpbm);
8657 ADD_IMAGE_TYPE (Qpbm);
8659 Qxbm = intern ("xbm");
8660 staticpro (&Qxbm);
8661 ADD_IMAGE_TYPE (Qxbm);
8663 define_image_type (&xbm_type, 1);
8664 define_image_type (&pbm_type, 1);
8666 Qcount = intern ("count");
8667 staticpro (&Qcount);
8669 QCascent = intern (":ascent");
8670 staticpro (&QCascent);
8671 QCmargin = intern (":margin");
8672 staticpro (&QCmargin);
8673 QCrelief = intern (":relief");
8674 staticpro (&QCrelief);
8675 QCconversion = intern (":conversion");
8676 staticpro (&QCconversion);
8677 QCcolor_symbols = intern (":color-symbols");
8678 staticpro (&QCcolor_symbols);
8679 QCheuristic_mask = intern (":heuristic-mask");
8680 staticpro (&QCheuristic_mask);
8681 QCindex = intern (":index");
8682 staticpro (&QCindex);
8683 QCmatrix = intern (":matrix");
8684 staticpro (&QCmatrix);
8685 QCcolor_adjustment = intern (":color-adjustment");
8686 staticpro (&QCcolor_adjustment);
8687 QCmask = intern (":mask");
8688 staticpro (&QCmask);
8690 Qlaplace = intern ("laplace");
8691 staticpro (&Qlaplace);
8692 Qemboss = intern ("emboss");
8693 staticpro (&Qemboss);
8694 Qedge_detection = intern ("edge-detection");
8695 staticpro (&Qedge_detection);
8696 Qheuristic = intern ("heuristic");
8697 staticpro (&Qheuristic);
8699 Qpostscript = intern ("postscript");
8700 staticpro (&Qpostscript);
8701 #ifdef HAVE_GHOSTSCRIPT
8702 ADD_IMAGE_TYPE (Qpostscript);
8703 QCloader = intern (":loader");
8704 staticpro (&QCloader);
8705 QCbounding_box = intern (":bounding-box");
8706 staticpro (&QCbounding_box);
8707 QCpt_width = intern (":pt-width");
8708 staticpro (&QCpt_width);
8709 QCpt_height = intern (":pt-height");
8710 staticpro (&QCpt_height);
8711 #endif /* HAVE_GHOSTSCRIPT */
8713 #if defined (HAVE_XPM) || defined (HAVE_NS)
8714 Qxpm = intern ("xpm");
8715 staticpro (&Qxpm);
8716 ADD_IMAGE_TYPE (Qxpm);
8717 #endif
8719 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8720 Qjpeg = intern ("jpeg");
8721 staticpro (&Qjpeg);
8722 ADD_IMAGE_TYPE (Qjpeg);
8723 #endif
8725 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8726 Qtiff = intern ("tiff");
8727 staticpro (&Qtiff);
8728 ADD_IMAGE_TYPE (Qtiff);
8729 #endif
8731 #if defined (HAVE_GIF) || defined (HAVE_NS)
8732 Qgif = intern ("gif");
8733 staticpro (&Qgif);
8734 ADD_IMAGE_TYPE (Qgif);
8735 #endif
8737 #if defined (HAVE_PNG) || defined (HAVE_NS)
8738 Qpng = intern ("png");
8739 staticpro (&Qpng);
8740 ADD_IMAGE_TYPE (Qpng);
8741 #endif
8743 #if defined (HAVE_RSVG)
8744 Qsvg = intern ("svg");
8745 staticpro (&Qsvg);
8746 ADD_IMAGE_TYPE (Qsvg);
8747 #ifdef HAVE_NTGUI
8748 Qgdk_pixbuf = intern ("gdk-pixbuf");
8749 staticpro (&Qgdk_pixbuf);
8750 Qglib = intern ("glib");
8751 staticpro (&Qglib);
8752 #endif /* HAVE_NTGUI */
8753 #endif /* HAVE_RSVG */
8755 defsubr (&Sinit_image_library);
8756 defsubr (&Sclear_image_cache);
8757 defsubr (&Simage_refresh);
8758 defsubr (&Simage_size);
8759 defsubr (&Simage_mask_p);
8760 defsubr (&Simage_extension_data);
8762 #if GLYPH_DEBUG
8763 defsubr (&Simagep);
8764 defsubr (&Slookup_image);
8765 #endif
8767 DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images,
8768 doc: /* Non-nil means always draw a cross over disabled images.
8769 Disabled images are those having a `:conversion disabled' property.
8770 A cross is always drawn on black & white displays. */);
8771 cross_disabled_images = 0;
8773 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
8774 doc: /* List of directories to search for window system bitmap files. */);
8775 Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS);
8777 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay,
8778 doc: /* Time after which cached images are removed from the cache.
8779 When an image has not been displayed this many seconds, remove it
8780 from the image cache. Value must be an integer or nil with nil
8781 meaning don't clear the cache. */);
8782 Vimage_cache_eviction_delay = make_number (30 * 60);
8785 void
8786 init_image ()
8790 /* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9
8791 (do not change this comment) */