Shrink EIEIO object header. Move generics to eieio-generic.el.
[emacs.git] / src / image.c
blobaddb932f83492564d140d984492ec5e200ea9afe
1 /* Functions for image support on window system.
3 Copyright (C) 1989, 1992-2015 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 #include <config.h>
21 #include "sysstdio.h"
22 #include <unistd.h>
24 /* Include this before including <setjmp.h> to work around bugs with
25 older libpng; see Bug#17429. */
26 #if defined HAVE_PNG && !defined HAVE_NS
27 # include <png.h>
28 #endif
30 #include <setjmp.h>
31 #include <c-ctype.h>
33 #include "lisp.h"
34 #include "frame.h"
35 #include "window.h"
36 #include "buffer.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_SYS_STAT_H
47 #include <sys/stat.h>
48 #endif /* HAVE_SYS_STAT_H */
50 #ifdef HAVE_SYS_TYPES_H
51 #include <sys/types.h>
52 #endif /* HAVE_SYS_TYPES_H */
54 #ifdef HAVE_WINDOW_SYSTEM
55 #include TERM_HEADER
56 #endif /* HAVE_WINDOW_SYSTEM */
58 #ifdef HAVE_X_WINDOWS
59 #define COLOR_TABLE_SUPPORT 1
61 typedef struct x_bitmap_record Bitmap_Record;
62 #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
63 #define NO_PIXMAP None
65 #define PIX_MASK_RETAIN 0
66 #define PIX_MASK_DRAW 1
67 #endif /* HAVE_X_WINDOWS */
69 #ifdef HAVE_NTGUI
71 /* We need (or want) w32.h only when we're _not_ compiling for Cygwin. */
72 #ifdef WINDOWSNT
73 # include "w32.h"
74 #endif
76 /* W32_TODO : Color tables on W32. */
77 #undef COLOR_TABLE_SUPPORT
79 typedef struct w32_bitmap_record Bitmap_Record;
80 #define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y)
81 #define NO_PIXMAP 0
83 #define PIX_MASK_RETAIN 0
84 #define PIX_MASK_DRAW 1
86 #define x_defined_color w32_defined_color
87 #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
89 #endif /* HAVE_NTGUI */
91 #ifdef HAVE_NS
92 #undef COLOR_TABLE_SUPPORT
94 typedef struct ns_bitmap_record Bitmap_Record;
96 #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
97 #define NO_PIXMAP 0
99 #define PIX_MASK_RETAIN 0
100 #define PIX_MASK_DRAW 1
102 #define x_defined_color(f, name, color_def, alloc) \
103 ns_defined_color (f, name, color_def, alloc, 0)
104 #define DefaultDepthOfScreen(screen) x_display_list->n_planes
105 #endif /* HAVE_NS */
107 static void x_disable_image (struct frame *, struct image *);
108 static void x_edge_detection (struct frame *, struct image *, Lisp_Object,
109 Lisp_Object);
111 static void init_color_table (void);
112 static unsigned long lookup_rgb_color (struct frame *f, int r, int g, int b);
113 #ifdef COLOR_TABLE_SUPPORT
114 static void free_color_table (void);
115 static unsigned long *colors_in_color_table (int *n);
116 #endif
118 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
119 id, which is just an int that this section returns. Bitmaps are
120 reference counted so they can be shared among frames.
122 Bitmap indices are guaranteed to be > 0, so a negative number can
123 be used to indicate no bitmap.
125 If you use x_create_bitmap_from_data, then you must keep track of
126 the bitmaps yourself. That is, creating a bitmap from the same
127 data more than once will not be caught. */
129 #ifdef HAVE_NS
130 /* Use with images created by ns_image_for_XPM. */
131 static unsigned long
132 XGetPixel (XImagePtr ximage, int x, int y)
134 return ns_get_pixel (ximage, x, y);
137 /* Use with images created by ns_image_for_XPM; alpha set to 1;
138 pixel is assumed to be in RGB form. */
139 static void
140 XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel)
142 ns_put_pixel (ximage, x, y, pixel);
144 #endif /* HAVE_NS */
147 /* Functions to access the contents of a bitmap, given an id. */
149 #ifdef HAVE_X_WINDOWS
150 static int
151 x_bitmap_height (struct frame *f, ptrdiff_t id)
153 return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].height;
156 static int
157 x_bitmap_width (struct frame *f, ptrdiff_t id)
159 return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].width;
161 #endif
163 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
164 ptrdiff_t
165 x_bitmap_pixmap (struct frame *f, ptrdiff_t id)
167 /* HAVE_NTGUI needs the explicit cast here. */
168 return (ptrdiff_t) FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
170 #endif
172 #ifdef HAVE_X_WINDOWS
174 x_bitmap_mask (struct frame *f, ptrdiff_t id)
176 return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].mask;
178 #endif
180 /* Allocate a new bitmap record. Returns index of new record. */
182 static ptrdiff_t
183 x_allocate_bitmap_record (struct frame *f)
185 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
186 ptrdiff_t i;
188 if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size)
189 return ++dpyinfo->bitmaps_last;
191 for (i = 0; i < dpyinfo->bitmaps_size; ++i)
192 if (dpyinfo->bitmaps[i].refcount == 0)
193 return i + 1;
195 dpyinfo->bitmaps =
196 xpalloc (dpyinfo->bitmaps, &dpyinfo->bitmaps_size,
197 10, -1, sizeof *dpyinfo->bitmaps);
198 return ++dpyinfo->bitmaps_last;
201 /* Add one reference to the reference count of the bitmap with id ID. */
203 void
204 x_reference_bitmap (struct frame *f, ptrdiff_t id)
206 ++FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
209 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
211 ptrdiff_t
212 x_create_bitmap_from_data (struct frame *f, char *bits, unsigned int width, unsigned int height)
214 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
215 ptrdiff_t id;
217 #ifdef HAVE_X_WINDOWS
218 Pixmap bitmap;
219 bitmap = XCreateBitmapFromData (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
220 bits, width, height);
221 if (! bitmap)
222 return -1;
223 #endif /* HAVE_X_WINDOWS */
225 #ifdef HAVE_NTGUI
226 Pixmap bitmap;
227 bitmap = CreateBitmap (width, height,
228 FRAME_DISPLAY_INFO (XFRAME (frame))->n_planes,
229 FRAME_DISPLAY_INFO (XFRAME (frame))->n_cbits,
230 bits);
231 if (! bitmap)
232 return -1;
233 #endif /* HAVE_NTGUI */
235 #ifdef HAVE_NS
236 void *bitmap = ns_image_from_XBM (bits, width, height);
237 if (!bitmap)
238 return -1;
239 #endif
241 id = x_allocate_bitmap_record (f);
243 #ifdef HAVE_NS
244 dpyinfo->bitmaps[id - 1].img = bitmap;
245 dpyinfo->bitmaps[id - 1].depth = 1;
246 #endif
248 dpyinfo->bitmaps[id - 1].file = NULL;
249 dpyinfo->bitmaps[id - 1].height = height;
250 dpyinfo->bitmaps[id - 1].width = width;
251 dpyinfo->bitmaps[id - 1].refcount = 1;
253 #ifdef HAVE_X_WINDOWS
254 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
255 dpyinfo->bitmaps[id - 1].have_mask = false;
256 dpyinfo->bitmaps[id - 1].depth = 1;
257 #endif /* HAVE_X_WINDOWS */
259 #ifdef HAVE_NTGUI
260 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
261 dpyinfo->bitmaps[id - 1].hinst = NULL;
262 dpyinfo->bitmaps[id - 1].depth = 1;
263 #endif /* HAVE_NTGUI */
265 return id;
268 /* Create bitmap from file FILE for frame F. */
270 ptrdiff_t
271 x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
273 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
275 #ifdef HAVE_NTGUI
276 return -1; /* W32_TODO : bitmap support */
277 #endif /* HAVE_NTGUI */
279 #ifdef HAVE_NS
280 ptrdiff_t id;
281 void *bitmap = ns_image_from_file (file);
283 if (!bitmap)
284 return -1;
287 id = x_allocate_bitmap_record (f);
288 dpyinfo->bitmaps[id - 1].img = bitmap;
289 dpyinfo->bitmaps[id - 1].refcount = 1;
290 dpyinfo->bitmaps[id - 1].file = xlispstrdup (file);
291 dpyinfo->bitmaps[id - 1].depth = 1;
292 dpyinfo->bitmaps[id - 1].height = ns_image_width (bitmap);
293 dpyinfo->bitmaps[id - 1].width = ns_image_height (bitmap);
294 return id;
295 #endif
297 #ifdef HAVE_X_WINDOWS
298 unsigned int width, height;
299 Pixmap bitmap;
300 int xhot, yhot, result;
301 ptrdiff_t id;
302 Lisp_Object found;
303 char *filename;
305 /* Look for an existing bitmap with the same name. */
306 for (id = 0; id < dpyinfo->bitmaps_last; ++id)
308 if (dpyinfo->bitmaps[id].refcount
309 && dpyinfo->bitmaps[id].file
310 && !strcmp (dpyinfo->bitmaps[id].file, SSDATA (file)))
312 ++dpyinfo->bitmaps[id].refcount;
313 return id + 1;
317 /* Search bitmap-file-path for the file, if appropriate. */
318 if (openp (Vx_bitmap_file_path, file, Qnil, &found,
319 make_number (R_OK), false)
320 < 0)
321 return -1;
323 filename = SSDATA (found);
325 result = XReadBitmapFile (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
326 filename, &width, &height, &bitmap, &xhot, &yhot);
327 if (result != BitmapSuccess)
328 return -1;
330 id = x_allocate_bitmap_record (f);
331 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
332 dpyinfo->bitmaps[id - 1].have_mask = false;
333 dpyinfo->bitmaps[id - 1].refcount = 1;
334 dpyinfo->bitmaps[id - 1].file = xlispstrdup (file);
335 dpyinfo->bitmaps[id - 1].depth = 1;
336 dpyinfo->bitmaps[id - 1].height = height;
337 dpyinfo->bitmaps[id - 1].width = width;
339 return id;
340 #endif /* HAVE_X_WINDOWS */
343 /* Free bitmap B. */
345 static void
346 free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm)
348 #ifdef HAVE_X_WINDOWS
349 XFreePixmap (dpyinfo->display, bm->pixmap);
350 if (bm->have_mask)
351 XFreePixmap (dpyinfo->display, bm->mask);
352 #endif /* HAVE_X_WINDOWS */
354 #ifdef HAVE_NTGUI
355 DeleteObject (bm->pixmap);
356 #endif /* HAVE_NTGUI */
358 #ifdef HAVE_NS
359 ns_release_object (bm->img);
360 #endif
362 if (bm->file)
364 xfree (bm->file);
365 bm->file = NULL;
369 /* Remove reference to bitmap with id number ID. */
371 void
372 x_destroy_bitmap (struct frame *f, ptrdiff_t id)
374 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
376 if (id > 0)
378 Bitmap_Record *bm = &dpyinfo->bitmaps[id - 1];
380 if (--bm->refcount == 0)
382 block_input ();
383 free_bitmap_record (dpyinfo, bm);
384 unblock_input ();
389 /* Free all the bitmaps for the display specified by DPYINFO. */
391 void
392 x_destroy_all_bitmaps (Display_Info *dpyinfo)
394 ptrdiff_t i;
395 Bitmap_Record *bm = dpyinfo->bitmaps;
397 for (i = 0; i < dpyinfo->bitmaps_last; i++, bm++)
398 if (bm->refcount > 0)
399 free_bitmap_record (dpyinfo, bm);
401 dpyinfo->bitmaps_last = 0;
404 static bool x_create_x_image_and_pixmap (struct frame *, int, int, int,
405 XImagePtr *, Pixmap *);
406 static void x_destroy_x_image (XImagePtr ximg);
408 #ifdef HAVE_NTGUI
409 static XImagePtr_or_DC image_get_x_image_or_dc (struct frame *, struct image *,
410 bool, HGDIOBJ *);
411 static void image_unget_x_image_or_dc (struct image *, bool, XImagePtr_or_DC,
412 HGDIOBJ);
413 #else
414 static XImagePtr image_get_x_image (struct frame *, struct image *, bool);
415 static void image_unget_x_image (struct image *, bool, XImagePtr);
416 #define image_get_x_image_or_dc(f, img, mask_p, dummy) \
417 image_get_x_image (f, img, mask_p)
418 #define image_unget_x_image_or_dc(img, mask_p, ximg, dummy) \
419 image_unget_x_image (img, mask_p, ximg)
420 #endif
422 #ifdef HAVE_X_WINDOWS
424 static void image_sync_to_pixmaps (struct frame *, struct image *);
426 /* Useful functions defined in the section
427 `Image type independent image structures' below. */
429 static unsigned long four_corners_best (XImagePtr ximg,
430 int *corners,
431 unsigned long width,
432 unsigned long height);
435 /* Create a mask of a bitmap. Note is this not a perfect mask.
436 It's nicer with some borders in this context */
438 void
439 x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
441 Pixmap pixmap, mask;
442 XImagePtr ximg, mask_img;
443 unsigned long width, height;
444 bool result;
445 unsigned long bg;
446 unsigned long x, y, xp, xm, yp, ym;
447 GC gc;
449 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
451 if (!(id > 0))
452 return;
454 pixmap = x_bitmap_pixmap (f, id);
455 width = x_bitmap_width (f, id);
456 height = x_bitmap_height (f, id);
458 block_input ();
459 ximg = XGetImage (FRAME_X_DISPLAY (f), pixmap, 0, 0, width, height,
460 ~0, ZPixmap);
462 if (!ximg)
464 unblock_input ();
465 return;
468 result = x_create_x_image_and_pixmap (f, width, height, 1, &mask_img, &mask);
470 unblock_input ();
471 if (!result)
473 XDestroyImage (ximg);
474 return;
477 bg = four_corners_best (ximg, NULL, width, height);
479 for (y = 0; y < ximg->height; ++y)
481 for (x = 0; x < ximg->width; ++x)
483 xp = x != ximg->width - 1 ? x + 1 : 0;
484 xm = x != 0 ? x - 1 : ximg->width - 1;
485 yp = y != ximg->height - 1 ? y + 1 : 0;
486 ym = y != 0 ? y - 1 : ximg->height - 1;
487 if (XGetPixel (ximg, x, y) == bg
488 && XGetPixel (ximg, x, yp) == bg
489 && XGetPixel (ximg, x, ym) == bg
490 && XGetPixel (ximg, xp, y) == bg
491 && XGetPixel (ximg, xp, yp) == bg
492 && XGetPixel (ximg, xp, ym) == bg
493 && XGetPixel (ximg, xm, y) == bg
494 && XGetPixel (ximg, xm, yp) == bg
495 && XGetPixel (ximg, xm, ym) == bg)
496 XPutPixel (mask_img, x, y, 0);
497 else
498 XPutPixel (mask_img, x, y, 1);
502 eassert (input_blocked_p ());
503 gc = XCreateGC (FRAME_X_DISPLAY (f), mask, 0, NULL);
504 XPutImage (FRAME_X_DISPLAY (f), mask, gc, mask_img, 0, 0, 0, 0,
505 width, height);
506 XFreeGC (FRAME_X_DISPLAY (f), gc);
508 dpyinfo->bitmaps[id - 1].have_mask = true;
509 dpyinfo->bitmaps[id - 1].mask = mask;
511 XDestroyImage (ximg);
512 x_destroy_x_image (mask_img);
515 #endif /* HAVE_X_WINDOWS */
518 /***********************************************************************
519 Image types
520 ***********************************************************************/
522 /* List of supported image types. Use define_image_type to add new
523 types. Use lookup_image_type to find a type for a given symbol. */
525 static struct image_type *image_types;
527 /* Forward function prototypes. */
529 static struct image_type *lookup_image_type (Lisp_Object);
530 static void x_laplace (struct frame *, struct image *);
531 static void x_emboss (struct frame *, struct image *);
532 static void x_build_heuristic_mask (struct frame *, struct image *,
533 Lisp_Object);
534 #ifdef WINDOWSNT
535 #define CACHE_IMAGE_TYPE(type, status) \
536 do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
537 #else
538 #define CACHE_IMAGE_TYPE(type, status)
539 #endif
541 #define ADD_IMAGE_TYPE(type) \
542 do { Vimage_types = Fcons (type, Vimage_types); } while (0)
544 /* Define a new image type from TYPE. This adds a copy of TYPE to
545 image_types and caches the loading status of TYPE. */
547 static struct image_type *
548 define_image_type (struct image_type *type)
550 struct image_type *p = NULL;
551 struct Lisp_Symbol *new_type = type->type;
552 bool type_valid = 1;
554 block_input ();
556 for (p = image_types; p; p = p->next)
557 if (p->type == new_type)
558 goto done;
560 if (type->init)
562 #if defined HAVE_NTGUI && defined WINDOWSNT
563 /* If we failed to load the library before, don't try again. */
564 Lisp_Object tested = Fassq (make_lisp_symbol (new_type), Vlibrary_cache);
565 if (CONSP (tested) && NILP (XCDR (tested)))
566 type_valid = 0;
567 else
568 #endif
570 type_valid = type->init ();
571 CACHE_IMAGE_TYPE (make_lisp_symbol (new_type),
572 type_valid ? Qt : Qnil);
576 if (type_valid)
578 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
579 The initialized data segment is read-only. */
580 p = xmalloc (sizeof *p);
581 *p = *type;
582 p->next = image_types;
583 image_types = p;
586 done:
587 unblock_input ();
588 return p;
592 /* Value is true if OBJECT is a valid Lisp image specification. A
593 valid image specification is a list whose car is the symbol
594 `image', and whose rest is a property list. The property list must
595 contain a value for key `:type'. That value must be the name of a
596 supported image type. The rest of the property list depends on the
597 image type. */
599 bool
600 valid_image_p (Lisp_Object object)
602 bool valid_p = 0;
604 if (IMAGEP (object))
606 Lisp_Object tem;
608 for (tem = XCDR (object); CONSP (tem); tem = XCDR (tem))
609 if (EQ (XCAR (tem), QCtype))
611 tem = XCDR (tem);
612 if (CONSP (tem) && SYMBOLP (XCAR (tem)))
614 struct image_type *type;
615 type = lookup_image_type (XCAR (tem));
616 if (type)
617 valid_p = type->valid_p (object);
620 break;
624 return valid_p;
628 /* Log error message with format string FORMAT and argument ARG.
629 Signaling an error, e.g. when an image cannot be loaded, is not a
630 good idea because this would interrupt redisplay, and the error
631 message display would lead to another redisplay. This function
632 therefore simply displays a message. */
634 static void
635 image_error (const char *format, Lisp_Object arg1, Lisp_Object arg2)
637 add_to_log (format, arg1, arg2);
642 /***********************************************************************
643 Image specifications
644 ***********************************************************************/
646 enum image_value_type
648 IMAGE_DONT_CHECK_VALUE_TYPE,
649 IMAGE_STRING_VALUE,
650 IMAGE_STRING_OR_NIL_VALUE,
651 IMAGE_SYMBOL_VALUE,
652 IMAGE_POSITIVE_INTEGER_VALUE,
653 IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR,
654 IMAGE_NON_NEGATIVE_INTEGER_VALUE,
655 IMAGE_ASCENT_VALUE,
656 IMAGE_INTEGER_VALUE,
657 IMAGE_FUNCTION_VALUE,
658 IMAGE_NUMBER_VALUE,
659 IMAGE_BOOL_VALUE
662 /* Structure used when parsing image specifications. */
664 struct image_keyword
666 /* Name of keyword. */
667 const char *name;
669 /* The type of value allowed. */
670 enum image_value_type type;
672 /* True means key must be present. */
673 bool mandatory_p;
675 /* Used to recognize duplicate keywords in a property list. */
676 int count;
678 /* The value that was found. */
679 Lisp_Object value;
683 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
684 has the format (image KEYWORD VALUE ...). One of the keyword/
685 value pairs must be `:type TYPE'. KEYWORDS is a vector of
686 image_keywords structures of size NKEYWORDS describing other
687 allowed keyword/value pairs. Value is true if SPEC is valid. */
689 static bool
690 parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
691 int nkeywords, Lisp_Object type)
693 int i;
694 Lisp_Object plist;
696 if (!IMAGEP (spec))
697 return 0;
699 plist = XCDR (spec);
700 while (CONSP (plist))
702 Lisp_Object key, value;
704 /* First element of a pair must be a symbol. */
705 key = XCAR (plist);
706 plist = XCDR (plist);
707 if (!SYMBOLP (key))
708 return 0;
710 /* There must follow a value. */
711 if (!CONSP (plist))
712 return 0;
713 value = XCAR (plist);
714 plist = XCDR (plist);
716 /* Find key in KEYWORDS. Error if not found. */
717 for (i = 0; i < nkeywords; ++i)
718 if (strcmp (keywords[i].name, SSDATA (SYMBOL_NAME (key))) == 0)
719 break;
721 if (i == nkeywords)
722 continue;
724 /* Record that we recognized the keyword. If a keywords
725 was found more than once, it's an error. */
726 keywords[i].value = value;
727 if (keywords[i].count > 1)
728 return 0;
729 ++keywords[i].count;
731 /* Check type of value against allowed type. */
732 switch (keywords[i].type)
734 case IMAGE_STRING_VALUE:
735 if (!STRINGP (value))
736 return 0;
737 break;
739 case IMAGE_STRING_OR_NIL_VALUE:
740 if (!STRINGP (value) && !NILP (value))
741 return 0;
742 break;
744 case IMAGE_SYMBOL_VALUE:
745 if (!SYMBOLP (value))
746 return 0;
747 break;
749 case IMAGE_POSITIVE_INTEGER_VALUE:
750 if (! RANGED_INTEGERP (1, value, INT_MAX))
751 return 0;
752 break;
754 case IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR:
755 if (RANGED_INTEGERP (0, value, INT_MAX))
756 break;
757 if (CONSP (value)
758 && RANGED_INTEGERP (0, XCAR (value), INT_MAX)
759 && RANGED_INTEGERP (0, XCDR (value), INT_MAX))
760 break;
761 return 0;
763 case IMAGE_ASCENT_VALUE:
764 if (SYMBOLP (value) && EQ (value, Qcenter))
765 break;
766 else if (RANGED_INTEGERP (0, value, 100))
767 break;
768 return 0;
770 case IMAGE_NON_NEGATIVE_INTEGER_VALUE:
771 /* Unlike the other integer-related cases, this one does not
772 verify that VALUE fits in 'int'. This is because callers
773 want EMACS_INT. */
774 if (!INTEGERP (value) || XINT (value) < 0)
775 return 0;
776 break;
778 case IMAGE_DONT_CHECK_VALUE_TYPE:
779 break;
781 case IMAGE_FUNCTION_VALUE:
782 value = indirect_function (value);
783 if (!NILP (Ffunctionp (value)))
784 break;
785 return 0;
787 case IMAGE_NUMBER_VALUE:
788 if (!INTEGERP (value) && !FLOATP (value))
789 return 0;
790 break;
792 case IMAGE_INTEGER_VALUE:
793 if (! TYPE_RANGED_INTEGERP (int, value))
794 return 0;
795 break;
797 case IMAGE_BOOL_VALUE:
798 if (!NILP (value) && !EQ (value, Qt))
799 return 0;
800 break;
802 default:
803 emacs_abort ();
804 break;
807 if (EQ (key, QCtype) && !EQ (type, value))
808 return 0;
811 /* Check that all mandatory fields are present. */
812 for (i = 0; i < nkeywords; ++i)
813 if (keywords[i].mandatory_p && keywords[i].count == 0)
814 return 0;
816 return NILP (plist);
820 /* Return the value of KEY in image specification SPEC. Value is nil
821 if KEY is not present in SPEC. Set *FOUND depending on whether KEY
822 was found in SPEC. */
824 static Lisp_Object
825 image_spec_value (Lisp_Object spec, Lisp_Object key, bool *found)
827 Lisp_Object tail;
829 eassert (valid_image_p (spec));
831 for (tail = XCDR (spec);
832 CONSP (tail) && CONSP (XCDR (tail));
833 tail = XCDR (XCDR (tail)))
835 if (EQ (XCAR (tail), key))
837 if (found)
838 *found = 1;
839 return XCAR (XCDR (tail));
843 if (found)
844 *found = 0;
845 return Qnil;
849 DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0,
850 doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
851 PIXELS non-nil means return the size in pixels, otherwise return the
852 size in canonical character units.
853 FRAME is the frame on which the image will be displayed. FRAME nil
854 or omitted means use the selected frame. */)
855 (Lisp_Object spec, Lisp_Object pixels, Lisp_Object frame)
857 Lisp_Object size;
859 size = Qnil;
860 if (valid_image_p (spec))
862 struct frame *f = decode_window_system_frame (frame);
863 ptrdiff_t id = lookup_image (f, spec);
864 struct image *img = IMAGE_FROM_ID (f, id);
865 int width = img->width + 2 * img->hmargin;
866 int height = img->height + 2 * img->vmargin;
868 if (NILP (pixels))
869 size = Fcons (make_float ((double) width / FRAME_COLUMN_WIDTH (f)),
870 make_float ((double) height / FRAME_LINE_HEIGHT (f)));
871 else
872 size = Fcons (make_number (width), make_number (height));
874 else
875 error ("Invalid image specification");
877 return size;
881 DEFUN ("image-mask-p", Fimage_mask_p, Simage_mask_p, 1, 2, 0,
882 doc: /* Return t if image SPEC has a mask bitmap.
883 FRAME is the frame on which the image will be displayed. FRAME nil
884 or omitted means use the selected frame. */)
885 (Lisp_Object spec, Lisp_Object frame)
887 Lisp_Object mask;
889 mask = Qnil;
890 if (valid_image_p (spec))
892 struct frame *f = decode_window_system_frame (frame);
893 ptrdiff_t id = lookup_image (f, spec);
894 struct image *img = IMAGE_FROM_ID (f, id);
895 if (img->mask)
896 mask = Qt;
898 else
899 error ("Invalid image specification");
901 return mask;
904 DEFUN ("image-metadata", Fimage_metadata, Simage_metadata, 1, 2, 0,
905 doc: /* Return metadata for image SPEC.
906 FRAME is the frame on which the image will be displayed. FRAME nil
907 or omitted means use the selected frame. */)
908 (Lisp_Object spec, Lisp_Object frame)
910 Lisp_Object ext;
912 ext = Qnil;
913 if (valid_image_p (spec))
915 struct frame *f = decode_window_system_frame (frame);
916 ptrdiff_t id = lookup_image (f, spec);
917 struct image *img = IMAGE_FROM_ID (f, id);
918 ext = img->lisp_data;
921 return ext;
925 /***********************************************************************
926 Image type independent image structures
927 ***********************************************************************/
929 #define MAX_IMAGE_SIZE 10.0
930 /* Allocate and return a new image structure for image specification
931 SPEC. SPEC has a hash value of HASH. */
933 static struct image *
934 make_image (Lisp_Object spec, EMACS_UINT hash)
936 struct image *img = xzalloc (sizeof *img);
937 Lisp_Object file = image_spec_value (spec, QCfile, NULL);
939 eassert (valid_image_p (spec));
940 img->dependencies = NILP (file) ? Qnil : list1 (file);
941 img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL));
942 eassert (img->type != NULL);
943 img->spec = spec;
944 img->lisp_data = Qnil;
945 img->ascent = DEFAULT_IMAGE_ASCENT;
946 img->hash = hash;
947 img->corners[BOT_CORNER] = -1; /* Full image */
948 return img;
952 /* Free image IMG which was used on frame F, including its resources. */
954 static void
955 free_image (struct frame *f, struct image *img)
957 if (img)
959 struct image_cache *c = FRAME_IMAGE_CACHE (f);
961 /* Remove IMG from the hash table of its cache. */
962 if (img->prev)
963 img->prev->next = img->next;
964 else
965 c->buckets[img->hash % IMAGE_CACHE_BUCKETS_SIZE] = img->next;
967 if (img->next)
968 img->next->prev = img->prev;
970 c->images[img->id] = NULL;
972 /* Windows NT redefines 'free', but in this file, we need to
973 avoid the redefinition. */
974 #ifdef WINDOWSNT
975 #undef free
976 #endif
977 /* Free resources, then free IMG. */
978 img->type->free (f, img);
979 xfree (img);
983 /* Return true if the given widths and heights are valid for display. */
985 static bool
986 check_image_size (struct frame *f, int width, int height)
988 int w, h;
990 if (width <= 0 || height <= 0)
991 return 0;
993 if (INTEGERP (Vmax_image_size))
994 return (width <= XINT (Vmax_image_size)
995 && height <= XINT (Vmax_image_size));
996 else if (FLOATP (Vmax_image_size))
998 if (f != NULL)
1000 w = FRAME_PIXEL_WIDTH (f);
1001 h = FRAME_PIXEL_HEIGHT (f);
1003 else
1004 w = h = 1024; /* Arbitrary size for unknown frame. */
1005 return (width <= XFLOAT_DATA (Vmax_image_size) * w
1006 && height <= XFLOAT_DATA (Vmax_image_size) * h);
1008 else
1009 return 1;
1012 /* Prepare image IMG for display on frame F. Must be called before
1013 drawing an image. */
1015 void
1016 prepare_image_for_display (struct frame *f, struct image *img)
1018 /* We're about to display IMG, so set its timestamp to `now'. */
1019 img->timestamp = current_timespec ();
1021 /* If IMG doesn't have a pixmap yet, load it now, using the image
1022 type dependent loader function. */
1023 if (img->pixmap == NO_PIXMAP && !img->load_failed_p)
1024 img->load_failed_p = ! img->type->load (f, img);
1026 #ifdef HAVE_X_WINDOWS
1027 if (!img->load_failed_p)
1029 block_input ();
1030 image_sync_to_pixmaps (f, img);
1031 unblock_input ();
1033 #endif
1037 /* Value is the number of pixels for the ascent of image IMG when
1038 drawn in face FACE. */
1041 image_ascent (struct image *img, struct face *face, struct glyph_slice *slice)
1043 int height;
1044 int ascent;
1046 if (slice->height == img->height)
1047 height = img->height + img->vmargin;
1048 else if (slice->y == 0)
1049 height = slice->height + img->vmargin;
1050 else
1051 height = slice->height;
1053 if (img->ascent == CENTERED_IMAGE_ASCENT)
1055 if (face->font)
1057 #ifdef HAVE_NTGUI
1058 /* W32 specific version. Why?. ++kfs */
1059 ascent = height / 2 - (FONT_DESCENT (face->font)
1060 - FONT_BASE (face->font)) / 2;
1061 #else
1062 /* This expression is arranged so that if the image can't be
1063 exactly centered, it will be moved slightly up. This is
1064 because a typical font is `top-heavy' (due to the presence
1065 uppercase letters), so the image placement should err towards
1066 being top-heavy too. It also just generally looks better. */
1067 ascent = (height + FONT_BASE (face->font)
1068 - FONT_DESCENT (face->font) + 1) / 2;
1069 #endif /* HAVE_NTGUI */
1071 else
1072 ascent = height / 2;
1074 else
1075 ascent = height * (img->ascent / 100.0);
1077 return ascent;
1081 /* Image background colors. */
1083 /* Find the "best" corner color of a bitmap.
1084 On W32, XIMG is assumed to a device context with the bitmap selected. */
1086 static RGB_PIXEL_COLOR
1087 four_corners_best (XImagePtr_or_DC ximg, int *corners,
1088 unsigned long width, unsigned long height)
1090 RGB_PIXEL_COLOR corner_pixels[4], best IF_LINT (= 0);
1091 int i, best_count;
1093 if (corners && corners[BOT_CORNER] >= 0)
1095 /* Get the colors at the corner_pixels of ximg. */
1096 corner_pixels[0] = GET_PIXEL (ximg, corners[LEFT_CORNER], corners[TOP_CORNER]);
1097 corner_pixels[1] = GET_PIXEL (ximg, corners[RIGHT_CORNER] - 1, corners[TOP_CORNER]);
1098 corner_pixels[2] = GET_PIXEL (ximg, corners[RIGHT_CORNER] - 1, corners[BOT_CORNER] - 1);
1099 corner_pixels[3] = GET_PIXEL (ximg, corners[LEFT_CORNER], corners[BOT_CORNER] - 1);
1101 else
1103 /* Get the colors at the corner_pixels of ximg. */
1104 corner_pixels[0] = GET_PIXEL (ximg, 0, 0);
1105 corner_pixels[1] = GET_PIXEL (ximg, width - 1, 0);
1106 corner_pixels[2] = GET_PIXEL (ximg, width - 1, height - 1);
1107 corner_pixels[3] = GET_PIXEL (ximg, 0, height - 1);
1109 /* Choose the most frequently found color as background. */
1110 for (i = best_count = 0; i < 4; ++i)
1112 int j, n;
1114 for (j = n = 0; j < 4; ++j)
1115 if (corner_pixels[i] == corner_pixels[j])
1116 ++n;
1118 if (n > best_count)
1119 best = corner_pixels[i], best_count = n;
1122 return best;
1125 /* Portability macros */
1127 #ifdef HAVE_NTGUI
1129 #define Free_Pixmap(display, pixmap) \
1130 DeleteObject (pixmap)
1132 #elif defined (HAVE_NS)
1134 #define Free_Pixmap(display, pixmap) \
1135 ns_release_object (pixmap)
1137 #else
1139 #define Free_Pixmap(display, pixmap) \
1140 XFreePixmap (display, pixmap)
1142 #endif /* !HAVE_NTGUI && !HAVE_NS */
1145 /* Return the `background' field of IMG. If IMG doesn't have one yet,
1146 it is guessed heuristically. If non-zero, XIMG is an existing
1147 XImage object (or device context with the image selected on W32) to
1148 use for the heuristic. */
1150 RGB_PIXEL_COLOR
1151 image_background (struct image *img, struct frame *f, XImagePtr_or_DC ximg)
1153 if (! img->background_valid)
1154 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1156 bool free_ximg = !ximg;
1157 #ifdef HAVE_NTGUI
1158 HGDIOBJ prev;
1159 #endif /* HAVE_NTGUI */
1161 if (free_ximg)
1162 ximg = image_get_x_image_or_dc (f, img, 0, &prev);
1164 img->background = four_corners_best (ximg, img->corners, img->width, img->height);
1166 if (free_ximg)
1167 image_unget_x_image_or_dc (img, 0, ximg, prev);
1169 img->background_valid = 1;
1172 return img->background;
1175 /* Return the `background_transparent' field of IMG. If IMG doesn't
1176 have one yet, it is guessed heuristically. If non-zero, MASK is an
1177 existing XImage object to use for the heuristic. */
1180 image_background_transparent (struct image *img, struct frame *f, XImagePtr_or_DC mask)
1182 if (! img->background_transparent_valid)
1183 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1185 if (img->mask)
1187 bool free_mask = !mask;
1188 #ifdef HAVE_NTGUI
1189 HGDIOBJ prev;
1190 #endif /* HAVE_NTGUI */
1192 if (free_mask)
1193 mask = image_get_x_image_or_dc (f, img, 1, &prev);
1195 img->background_transparent
1196 = (four_corners_best (mask, img->corners, img->width, img->height) == PIX_MASK_RETAIN);
1198 if (free_mask)
1199 image_unget_x_image_or_dc (img, 1, mask, prev);
1201 else
1202 img->background_transparent = 0;
1204 img->background_transparent_valid = 1;
1207 return img->background_transparent;
1210 #if defined (HAVE_PNG) || defined (HAVE_NS) \
1211 || defined (HAVE_IMAGEMAGICK) || defined (HAVE_RSVG)
1213 /* Store F's background color into *BGCOLOR. */
1214 static void
1215 x_query_frame_background_color (struct frame *f, XColor *bgcolor)
1217 #ifndef HAVE_NS
1218 bgcolor->pixel = FRAME_BACKGROUND_PIXEL (f);
1219 x_query_color (f, bgcolor);
1220 #else
1221 ns_query_color (FRAME_BACKGROUND_COLOR (f), bgcolor, 1);
1222 #endif
1225 #endif /* HAVE_PNG || HAVE_NS || HAVE_IMAGEMAGICK || HAVE_RSVG */
1227 /***********************************************************************
1228 Helper functions for X image types
1229 ***********************************************************************/
1231 /* Clear X resources of image IMG on frame F according to FLAGS.
1232 FLAGS is bitwise-or of the following masks:
1233 CLEAR_IMAGE_PIXMAP free the pixmap if any.
1234 CLEAR_IMAGE_MASK means clear the mask pixmap if any.
1235 CLEAR_IMAGE_COLORS means free colors allocated for the image, if
1236 any. */
1238 #define CLEAR_IMAGE_PIXMAP (1 << 0)
1239 #define CLEAR_IMAGE_MASK (1 << 1)
1240 #define CLEAR_IMAGE_COLORS (1 << 2)
1242 static void
1243 x_clear_image_1 (struct frame *f, struct image *img, int flags)
1245 if (flags & CLEAR_IMAGE_PIXMAP)
1247 if (img->pixmap)
1249 Free_Pixmap (FRAME_X_DISPLAY (f), img->pixmap);
1250 img->pixmap = NO_PIXMAP;
1251 /* NOTE (HAVE_NS): background color is NOT an indexed color! */
1252 img->background_valid = 0;
1254 #ifdef HAVE_X_WINDOWS
1255 if (img->ximg)
1257 x_destroy_x_image (img->ximg);
1258 img->ximg = NULL;
1259 img->background_valid = 0;
1261 #endif
1264 if (flags & CLEAR_IMAGE_MASK)
1266 if (img->mask)
1268 Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
1269 img->mask = NO_PIXMAP;
1270 img->background_transparent_valid = 0;
1272 #ifdef HAVE_X_WINDOWS
1273 if (img->mask_img)
1275 x_destroy_x_image (img->mask_img);
1276 img->mask_img = NULL;
1277 img->background_transparent_valid = 0;
1279 #endif
1282 if ((flags & CLEAR_IMAGE_COLORS) && img->ncolors)
1284 /* W32_TODO: color table support. */
1285 #ifdef HAVE_X_WINDOWS
1286 x_free_colors (f, img->colors, img->ncolors);
1287 #endif /* HAVE_X_WINDOWS */
1288 xfree (img->colors);
1289 img->colors = NULL;
1290 img->ncolors = 0;
1295 /* Free X resources of image IMG which is used on frame F. */
1297 static void
1298 x_clear_image (struct frame *f, struct image *img)
1300 block_input ();
1301 x_clear_image_1 (f, img,
1302 CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_MASK | CLEAR_IMAGE_COLORS);
1303 unblock_input ();
1307 /* Allocate color COLOR_NAME for image IMG on frame F. If color
1308 cannot be allocated, use DFLT. Add a newly allocated color to
1309 IMG->colors, so that it can be freed again. Value is the pixel
1310 color. */
1312 static unsigned long
1313 x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name,
1314 unsigned long dflt)
1316 XColor color;
1317 unsigned long result;
1319 eassert (STRINGP (color_name));
1321 if (x_defined_color (f, SSDATA (color_name), &color, 1)
1322 && img->ncolors < min (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *img->colors,
1323 INT_MAX))
1325 /* This isn't called frequently so we get away with simply
1326 reallocating the color vector to the needed size, here. */
1327 ptrdiff_t ncolors = img->ncolors + 1;
1328 img->colors = xrealloc (img->colors, ncolors * sizeof *img->colors);
1329 img->colors[ncolors - 1] = color.pixel;
1330 img->ncolors = ncolors;
1331 result = color.pixel;
1333 else
1334 result = dflt;
1336 return result;
1341 /***********************************************************************
1342 Image Cache
1343 ***********************************************************************/
1345 static void cache_image (struct frame *f, struct image *img);
1347 /* Return a new, initialized image cache that is allocated from the
1348 heap. Call free_image_cache to free an image cache. */
1350 struct image_cache *
1351 make_image_cache (void)
1353 struct image_cache *c = xmalloc (sizeof *c);
1355 c->size = 50;
1356 c->used = c->refcount = 0;
1357 c->images = xmalloc (c->size * sizeof *c->images);
1358 c->buckets = xzalloc (IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets);
1359 return c;
1363 /* Find an image matching SPEC in the cache, and return it. If no
1364 image is found, return NULL. */
1365 static struct image *
1366 search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash)
1368 struct image *img;
1369 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1370 int i = hash % IMAGE_CACHE_BUCKETS_SIZE;
1372 if (!c) return NULL;
1374 /* If the image spec does not specify a background color, the cached
1375 image must have the same background color as the current frame.
1376 The foreground color must also match, for the sake of monochrome
1377 images.
1379 In fact, we could ignore the foreground color matching condition
1380 for color images, or if the image spec specifies :foreground;
1381 similarly we could ignore the background color matching condition
1382 for formats that don't use transparency (such as jpeg), or if the
1383 image spec specifies :background. However, the extra memory
1384 usage is probably negligible in practice, so we don't bother. */
1386 for (img = c->buckets[i]; img; img = img->next)
1387 if (img->hash == hash
1388 && !NILP (Fequal (img->spec, spec))
1389 && img->frame_foreground == FRAME_FOREGROUND_PIXEL (f)
1390 && img->frame_background == FRAME_BACKGROUND_PIXEL (f))
1391 break;
1392 return img;
1396 /* Search frame F for an image with spec SPEC, and free it. */
1398 static void
1399 uncache_image (struct frame *f, Lisp_Object spec)
1401 struct image *img = search_image_cache (f, spec, sxhash (spec, 0));
1402 if (img)
1404 free_image (f, img);
1405 /* As display glyphs may still be referring to the image ID, we
1406 must garbage the frame (Bug#6426). */
1407 SET_FRAME_GARBAGED (f);
1412 /* Free image cache of frame F. Be aware that X frames share images
1413 caches. */
1415 void
1416 free_image_cache (struct frame *f)
1418 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1419 if (c)
1421 ptrdiff_t i;
1423 /* Cache should not be referenced by any frame when freed. */
1424 eassert (c->refcount == 0);
1426 for (i = 0; i < c->used; ++i)
1427 free_image (f, c->images[i]);
1428 xfree (c->images);
1429 xfree (c->buckets);
1430 xfree (c);
1431 FRAME_IMAGE_CACHE (f) = NULL;
1436 /* Clear image cache of frame F. FILTER=t means free all images.
1437 FILTER=nil means clear only images that haven't been
1438 displayed for some time.
1439 Else, only free the images which have FILTER in their `dependencies'.
1440 Should be called from time to time to reduce the number of loaded images.
1441 If image-cache-eviction-delay is non-nil, this frees images in the cache
1442 which weren't displayed for at least that many seconds. */
1444 static void
1445 clear_image_cache (struct frame *f, Lisp_Object filter)
1447 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1449 if (c)
1451 ptrdiff_t i, nfreed = 0;
1453 /* Block input so that we won't be interrupted by a SIGIO
1454 while being in an inconsistent state. */
1455 block_input ();
1457 if (!NILP (filter))
1459 /* Filter image cache. */
1460 for (i = 0; i < c->used; ++i)
1462 struct image *img = c->images[i];
1463 if (img && (EQ (Qt, filter)
1464 || !NILP (Fmember (filter, img->dependencies))))
1466 free_image (f, img);
1467 ++nfreed;
1471 else if (INTEGERP (Vimage_cache_eviction_delay))
1473 /* Free cache based on timestamp. */
1474 struct timespec old, t;
1475 double delay;
1476 ptrdiff_t nimages = 0;
1478 for (i = 0; i < c->used; ++i)
1479 if (c->images[i])
1480 nimages++;
1482 /* If the number of cached images has grown unusually large,
1483 decrease the cache eviction delay (Bug#6230). */
1484 delay = XINT (Vimage_cache_eviction_delay);
1485 if (nimages > 40)
1486 delay = 1600 * delay / nimages / nimages;
1487 delay = max (delay, 1);
1489 t = current_timespec ();
1490 old = timespec_sub (t, dtotimespec (delay));
1492 for (i = 0; i < c->used; ++i)
1494 struct image *img = c->images[i];
1495 if (img && timespec_cmp (img->timestamp, old) < 0)
1497 free_image (f, img);
1498 ++nfreed;
1503 /* We may be clearing the image cache because, for example,
1504 Emacs was iconified for a longer period of time. In that
1505 case, current matrices may still contain references to
1506 images freed above. So, clear these matrices. */
1507 if (nfreed)
1509 Lisp_Object tail, frame;
1511 FOR_EACH_FRAME (tail, frame)
1513 struct frame *fr = XFRAME (frame);
1514 if (FRAME_IMAGE_CACHE (fr) == c)
1515 clear_current_matrices (fr);
1518 windows_or_buffers_changed = 19;
1521 unblock_input ();
1525 void
1526 clear_image_caches (Lisp_Object filter)
1528 /* FIXME: We want to do
1529 * struct terminal *t;
1530 * for (t = terminal_list; t; t = t->next_terminal)
1531 * clear_image_cache (t, filter); */
1532 Lisp_Object tail, frame;
1533 FOR_EACH_FRAME (tail, frame)
1534 if (FRAME_WINDOW_P (XFRAME (frame)))
1535 clear_image_cache (XFRAME (frame), filter);
1538 DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache,
1539 0, 1, 0,
1540 doc: /* Clear the image cache.
1541 FILTER nil or a frame means clear all images in the selected frame.
1542 FILTER t means clear the image caches of all frames.
1543 Anything else, means only clear those images which refer to FILTER,
1544 which is then usually a filename. */)
1545 (Lisp_Object filter)
1547 if (!(EQ (filter, Qnil) || FRAMEP (filter)))
1548 clear_image_caches (filter);
1549 else
1550 clear_image_cache (decode_window_system_frame (filter), Qt);
1552 return Qnil;
1556 DEFUN ("image-flush", Fimage_flush, Simage_flush,
1557 1, 2, 0,
1558 doc: /* Flush the image with specification SPEC on frame FRAME.
1559 This removes the image from the Emacs image cache. If SPEC specifies
1560 an image file, the next redisplay of this image will read from the
1561 current contents of that file.
1563 FRAME nil or omitted means use the selected frame.
1564 FRAME t means refresh the image on all frames. */)
1565 (Lisp_Object spec, Lisp_Object frame)
1567 if (!valid_image_p (spec))
1568 error ("Invalid image specification");
1570 if (EQ (frame, Qt))
1572 Lisp_Object tail;
1573 FOR_EACH_FRAME (tail, frame)
1575 struct frame *f = XFRAME (frame);
1576 if (FRAME_WINDOW_P (f))
1577 uncache_image (f, spec);
1580 else
1581 uncache_image (decode_window_system_frame (frame), spec);
1583 return Qnil;
1587 /* Compute masks and transform image IMG on frame F, as specified
1588 by the image's specification, */
1590 static void
1591 postprocess_image (struct frame *f, struct image *img)
1593 /* Manipulation of the image's mask. */
1594 if (img->pixmap)
1596 Lisp_Object conversion, spec;
1597 Lisp_Object mask;
1599 spec = img->spec;
1601 /* `:heuristic-mask t'
1602 `:mask heuristic'
1603 means build a mask heuristically.
1604 `:heuristic-mask (R G B)'
1605 `:mask (heuristic (R G B))'
1606 means build a mask from color (R G B) in the
1607 image.
1608 `:mask nil'
1609 means remove a mask, if any. */
1611 mask = image_spec_value (spec, QCheuristic_mask, NULL);
1612 if (!NILP (mask))
1613 x_build_heuristic_mask (f, img, mask);
1614 else
1616 bool found_p;
1618 mask = image_spec_value (spec, QCmask, &found_p);
1620 if (EQ (mask, Qheuristic))
1621 x_build_heuristic_mask (f, img, Qt);
1622 else if (CONSP (mask)
1623 && EQ (XCAR (mask), Qheuristic))
1625 if (CONSP (XCDR (mask)))
1626 x_build_heuristic_mask (f, img, XCAR (XCDR (mask)));
1627 else
1628 x_build_heuristic_mask (f, img, XCDR (mask));
1630 else if (NILP (mask) && found_p && img->mask)
1631 x_clear_image_1 (f, img, CLEAR_IMAGE_MASK);
1635 /* Should we apply an image transformation algorithm? */
1636 conversion = image_spec_value (spec, QCconversion, NULL);
1637 if (EQ (conversion, Qdisabled))
1638 x_disable_image (f, img);
1639 else if (EQ (conversion, Qlaplace))
1640 x_laplace (f, img);
1641 else if (EQ (conversion, Qemboss))
1642 x_emboss (f, img);
1643 else if (CONSP (conversion)
1644 && EQ (XCAR (conversion), Qedge_detection))
1646 Lisp_Object tem;
1647 tem = XCDR (conversion);
1648 if (CONSP (tem))
1649 x_edge_detection (f, img,
1650 Fplist_get (tem, QCmatrix),
1651 Fplist_get (tem, QCcolor_adjustment));
1657 /* Return the id of image with Lisp specification SPEC on frame F.
1658 SPEC must be a valid Lisp image specification (see valid_image_p). */
1660 ptrdiff_t
1661 lookup_image (struct frame *f, Lisp_Object spec)
1663 struct image *img;
1664 EMACS_UINT hash;
1666 /* F must be a window-system frame, and SPEC must be a valid image
1667 specification. */
1668 eassert (FRAME_WINDOW_P (f));
1669 eassert (valid_image_p (spec));
1671 /* Look up SPEC in the hash table of the image cache. */
1672 hash = sxhash (spec, 0);
1673 img = search_image_cache (f, spec, hash);
1674 if (img && img->load_failed_p)
1676 free_image (f, img);
1677 img = NULL;
1680 /* If not found, create a new image and cache it. */
1681 if (img == NULL)
1683 block_input ();
1684 img = make_image (spec, hash);
1685 cache_image (f, img);
1686 img->load_failed_p = ! img->type->load (f, img);
1687 img->frame_foreground = FRAME_FOREGROUND_PIXEL (f);
1688 img->frame_background = FRAME_BACKGROUND_PIXEL (f);
1690 /* If we can't load the image, and we don't have a width and
1691 height, use some arbitrary width and height so that we can
1692 draw a rectangle for it. */
1693 if (img->load_failed_p)
1695 Lisp_Object value;
1697 value = image_spec_value (spec, QCwidth, NULL);
1698 img->width = (INTEGERP (value)
1699 ? XFASTINT (value) : DEFAULT_IMAGE_WIDTH);
1700 value = image_spec_value (spec, QCheight, NULL);
1701 img->height = (INTEGERP (value)
1702 ? XFASTINT (value) : DEFAULT_IMAGE_HEIGHT);
1704 else
1706 /* Handle image type independent image attributes
1707 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
1708 `:background COLOR'. */
1709 Lisp_Object ascent, margin, relief, bg;
1710 int relief_bound;
1712 ascent = image_spec_value (spec, QCascent, NULL);
1713 if (INTEGERP (ascent))
1714 img->ascent = XFASTINT (ascent);
1715 else if (EQ (ascent, Qcenter))
1716 img->ascent = CENTERED_IMAGE_ASCENT;
1718 margin = image_spec_value (spec, QCmargin, NULL);
1719 if (INTEGERP (margin))
1720 img->vmargin = img->hmargin = XFASTINT (margin);
1721 else if (CONSP (margin))
1723 img->hmargin = XFASTINT (XCAR (margin));
1724 img->vmargin = XFASTINT (XCDR (margin));
1727 relief = image_spec_value (spec, QCrelief, NULL);
1728 relief_bound = INT_MAX - max (img->hmargin, img->vmargin);
1729 if (RANGED_INTEGERP (- relief_bound, relief, relief_bound))
1731 img->relief = XINT (relief);
1732 img->hmargin += eabs (img->relief);
1733 img->vmargin += eabs (img->relief);
1736 if (! img->background_valid)
1738 bg = image_spec_value (img->spec, QCbackground, NULL);
1739 if (!NILP (bg))
1741 img->background
1742 = x_alloc_image_color (f, img, bg,
1743 FRAME_BACKGROUND_PIXEL (f));
1744 img->background_valid = 1;
1748 /* Do image transformations and compute masks, unless we
1749 don't have the image yet. */
1750 if (!EQ (make_lisp_symbol (img->type->type), Qpostscript))
1751 postprocess_image (f, img);
1754 unblock_input ();
1757 /* We're using IMG, so set its timestamp to `now'. */
1758 img->timestamp = current_timespec ();
1760 /* Value is the image id. */
1761 return img->id;
1765 /* Cache image IMG in the image cache of frame F. */
1767 static void
1768 cache_image (struct frame *f, struct image *img)
1770 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1771 ptrdiff_t i;
1773 /* Find a free slot in c->images. */
1774 for (i = 0; i < c->used; ++i)
1775 if (c->images[i] == NULL)
1776 break;
1778 /* If no free slot found, maybe enlarge c->images. */
1779 if (i == c->used && c->used == c->size)
1780 c->images = xpalloc (c->images, &c->size, 1, -1, sizeof *c->images);
1782 /* Add IMG to c->images, and assign IMG an id. */
1783 c->images[i] = img;
1784 img->id = i;
1785 if (i == c->used)
1786 ++c->used;
1788 /* Add IMG to the cache's hash table. */
1789 i = img->hash % IMAGE_CACHE_BUCKETS_SIZE;
1790 img->next = c->buckets[i];
1791 if (img->next)
1792 img->next->prev = img;
1793 img->prev = NULL;
1794 c->buckets[i] = img;
1798 /* Call FN on every image in the image cache of frame F. Used to mark
1799 Lisp Objects in the image cache. */
1801 /* Mark Lisp objects in image IMG. */
1803 static void
1804 mark_image (struct image *img)
1806 mark_object (img->spec);
1807 mark_object (img->dependencies);
1809 if (!NILP (img->lisp_data))
1810 mark_object (img->lisp_data);
1814 void
1815 mark_image_cache (struct image_cache *c)
1817 if (c)
1819 ptrdiff_t i;
1820 for (i = 0; i < c->used; ++i)
1821 if (c->images[i])
1822 mark_image (c->images[i]);
1828 /***********************************************************************
1829 X / NS / W32 support code
1830 ***********************************************************************/
1832 /* Return true if XIMG's size WIDTH x HEIGHT doesn't break the
1833 windowing system.
1834 WIDTH and HEIGHT must both be positive.
1835 If XIMG is null, assume it is a bitmap. */
1836 static bool
1837 x_check_image_size (XImagePtr ximg, int width, int height)
1839 #ifdef HAVE_X_WINDOWS
1840 /* Respect Xlib's limits: it cannot deal with images that have more
1841 than INT_MAX (and/or UINT_MAX) bytes. And respect Emacs's limits
1842 of PTRDIFF_MAX (and/or SIZE_MAX) bytes for any object. */
1843 enum
1845 XLIB_BYTES_MAX = min (INT_MAX, UINT_MAX),
1846 X_IMAGE_BYTES_MAX = min (XLIB_BYTES_MAX, min (PTRDIFF_MAX, SIZE_MAX))
1849 int bitmap_pad, depth, bytes_per_line;
1850 if (ximg)
1852 bitmap_pad = ximg->bitmap_pad;
1853 depth = ximg->depth;
1854 bytes_per_line = ximg->bytes_per_line;
1856 else
1858 bitmap_pad = 8;
1859 depth = 1;
1860 bytes_per_line = (width >> 3) + ((width & 7) != 0);
1862 return (width <= (INT_MAX - (bitmap_pad - 1)) / depth
1863 && height <= X_IMAGE_BYTES_MAX / bytes_per_line);
1864 #else
1865 /* FIXME: Implement this check for the HAVE_NS and HAVE_NTGUI cases.
1866 For now, assume that every image size is allowed on these systems. */
1867 return 1;
1868 #endif
1871 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
1872 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
1873 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
1874 via xmalloc. Print error messages via image_error if an error
1875 occurs. Value is true if successful.
1877 On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
1878 should indicate the bit depth of the image. */
1880 static bool
1881 x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
1882 XImagePtr *ximg, Pixmap *pixmap)
1884 #ifdef HAVE_X_WINDOWS
1885 Display *display = FRAME_X_DISPLAY (f);
1886 Window window = FRAME_X_WINDOW (f);
1887 Screen *screen = FRAME_X_SCREEN (f);
1889 eassert (input_blocked_p ());
1891 if (depth <= 0)
1892 depth = DefaultDepthOfScreen (screen);
1893 *ximg = XCreateImage (display, DefaultVisualOfScreen (screen),
1894 depth, ZPixmap, 0, NULL, width, height,
1895 depth > 16 ? 32 : depth > 8 ? 16 : 8, 0);
1896 if (*ximg == NULL)
1898 image_error ("Unable to allocate X image", Qnil, Qnil);
1899 return 0;
1902 if (! x_check_image_size (*ximg, width, height))
1904 x_destroy_x_image (*ximg);
1905 *ximg = NULL;
1906 image_error ("Image too large (%dx%d)",
1907 make_number (width), make_number (height));
1908 return 0;
1911 /* Allocate image raster. */
1912 (*ximg)->data = xmalloc ((*ximg)->bytes_per_line * height);
1914 /* Allocate a pixmap of the same size. */
1915 *pixmap = XCreatePixmap (display, window, width, height, depth);
1916 if (*pixmap == NO_PIXMAP)
1918 x_destroy_x_image (*ximg);
1919 *ximg = NULL;
1920 image_error ("Unable to create X pixmap", Qnil, Qnil);
1921 return 0;
1924 return 1;
1925 #endif /* HAVE_X_WINDOWS */
1927 #ifdef HAVE_NTGUI
1929 BITMAPINFOHEADER *header;
1930 HDC hdc;
1931 int scanline_width_bits;
1932 int remainder;
1933 int palette_colors = 0;
1935 if (depth == 0)
1936 depth = 24;
1938 if (depth != 1 && depth != 4 && depth != 8
1939 && depth != 16 && depth != 24 && depth != 32)
1941 image_error ("Invalid image bit depth specified", Qnil, Qnil);
1942 return 0;
1945 scanline_width_bits = width * depth;
1946 remainder = scanline_width_bits % 32;
1948 if (remainder)
1949 scanline_width_bits += 32 - remainder;
1951 /* Bitmaps with a depth less than 16 need a palette. */
1952 /* BITMAPINFO structure already contains the first RGBQUAD. */
1953 if (depth < 16)
1954 palette_colors = 1 << (depth - 1);
1956 *ximg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD));
1958 header = &(*ximg)->info.bmiHeader;
1959 memset (&(*ximg)->info, 0, sizeof (BITMAPINFO));
1960 header->biSize = sizeof (*header);
1961 header->biWidth = width;
1962 header->biHeight = -height; /* negative indicates a top-down bitmap. */
1963 header->biPlanes = 1;
1964 header->biBitCount = depth;
1965 header->biCompression = BI_RGB;
1966 header->biClrUsed = palette_colors;
1968 /* TODO: fill in palette. */
1969 if (depth == 1)
1971 (*ximg)->info.bmiColors[0].rgbBlue = 0;
1972 (*ximg)->info.bmiColors[0].rgbGreen = 0;
1973 (*ximg)->info.bmiColors[0].rgbRed = 0;
1974 (*ximg)->info.bmiColors[0].rgbReserved = 0;
1975 (*ximg)->info.bmiColors[1].rgbBlue = 255;
1976 (*ximg)->info.bmiColors[1].rgbGreen = 255;
1977 (*ximg)->info.bmiColors[1].rgbRed = 255;
1978 (*ximg)->info.bmiColors[1].rgbReserved = 0;
1981 hdc = get_frame_dc (f);
1983 /* Create a DIBSection and raster array for the bitmap,
1984 and store its handle in *pixmap. */
1985 *pixmap = CreateDIBSection (hdc, &((*ximg)->info),
1986 (depth < 16) ? DIB_PAL_COLORS : DIB_RGB_COLORS,
1987 /* casting avoids a GCC warning */
1988 (void **)&((*ximg)->data), NULL, 0);
1990 /* Realize display palette and garbage all frames. */
1991 release_frame_dc (f, hdc);
1993 if (*pixmap == NULL)
1995 DWORD err = GetLastError ();
1996 Lisp_Object errcode;
1997 /* All system errors are < 10000, so the following is safe. */
1998 XSETINT (errcode, err);
1999 image_error ("Unable to create bitmap, error code %d", errcode, Qnil);
2000 x_destroy_x_image (*ximg);
2001 *ximg = NULL;
2002 return 0;
2005 return 1;
2007 #endif /* HAVE_NTGUI */
2009 #ifdef HAVE_NS
2010 *pixmap = ns_image_for_XPM (width, height, depth);
2011 if (*pixmap == 0)
2013 *ximg = NULL;
2014 image_error ("Unable to allocate NSImage for XPM pixmap", Qnil, Qnil);
2015 return 0;
2017 *ximg = *pixmap;
2018 return 1;
2019 #endif
2023 /* Destroy XImage XIMG. Free XIMG->data. */
2025 static void
2026 x_destroy_x_image (XImagePtr ximg)
2028 eassert (input_blocked_p ());
2029 if (ximg)
2031 #ifdef HAVE_X_WINDOWS
2032 xfree (ximg->data);
2033 ximg->data = NULL;
2034 XDestroyImage (ximg);
2035 #endif /* HAVE_X_WINDOWS */
2036 #ifdef HAVE_NTGUI
2037 /* Data will be freed by DestroyObject. */
2038 ximg->data = NULL;
2039 xfree (ximg);
2040 #endif /* HAVE_NTGUI */
2041 #ifdef HAVE_NS
2042 ns_release_object (ximg);
2043 #endif /* HAVE_NS */
2048 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
2049 are width and height of both the image and pixmap. */
2051 static void
2052 x_put_x_image (struct frame *f, XImagePtr ximg, Pixmap pixmap, int width, int height)
2054 #ifdef HAVE_X_WINDOWS
2055 GC gc;
2057 eassert (input_blocked_p ());
2058 gc = XCreateGC (FRAME_X_DISPLAY (f), pixmap, 0, NULL);
2059 XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, ximg, 0, 0, 0, 0, width, height);
2060 XFreeGC (FRAME_X_DISPLAY (f), gc);
2061 #endif /* HAVE_X_WINDOWS */
2063 #ifdef HAVE_NTGUI
2064 #if 0 /* I don't think this is necessary looking at where it is used. */
2065 HDC hdc = get_frame_dc (f);
2066 SetDIBits (hdc, pixmap, 0, height, ximg->data, &(ximg->info), DIB_RGB_COLORS);
2067 release_frame_dc (f, hdc);
2068 #endif
2069 #endif /* HAVE_NTGUI */
2071 #ifdef HAVE_NS
2072 eassert (ximg == pixmap);
2073 ns_retain_object (ximg);
2074 #endif
2077 /* Thin wrapper for x_create_x_image_and_pixmap, so that it matches
2078 with image_put_x_image. */
2080 static bool
2081 image_create_x_image_and_pixmap (struct frame *f, struct image *img,
2082 int width, int height, int depth,
2083 XImagePtr *ximg, bool mask_p)
2085 eassert ((!mask_p ? img->pixmap : img->mask) == NO_PIXMAP);
2087 return x_create_x_image_and_pixmap (f, width, height, depth, ximg,
2088 !mask_p ? &img->pixmap : &img->mask);
2091 /* Put X image XIMG into image IMG on frame F, as a mask if and only
2092 if MASK_P. On X, this simply records XIMG on a member of IMG, so
2093 it can be put into the pixmap afterwards via image_sync_to_pixmaps.
2094 On the other platforms, it puts XIMG into the pixmap, then frees
2095 the X image and its buffer. */
2097 static void
2098 image_put_x_image (struct frame *f, struct image *img, XImagePtr ximg,
2099 bool mask_p)
2101 #ifdef HAVE_X_WINDOWS
2102 if (!mask_p)
2104 eassert (img->ximg == NULL);
2105 img->ximg = ximg;
2107 else
2109 eassert (img->mask_img == NULL);
2110 img->mask_img = ximg;
2112 #else
2113 x_put_x_image (f, ximg, !mask_p ? img->pixmap : img->mask,
2114 img->width, img->height);
2115 x_destroy_x_image (ximg);
2116 #endif
2119 #ifdef HAVE_X_WINDOWS
2120 /* Put the X images recorded in IMG on frame F into pixmaps, then free
2121 the X images and their buffers. */
2123 static void
2124 image_sync_to_pixmaps (struct frame *f, struct image *img)
2126 if (img->ximg)
2128 x_put_x_image (f, img->ximg, img->pixmap, img->width, img->height);
2129 x_destroy_x_image (img->ximg);
2130 img->ximg = NULL;
2132 if (img->mask_img)
2134 x_put_x_image (f, img->mask_img, img->mask, img->width, img->height);
2135 x_destroy_x_image (img->mask_img);
2136 img->mask_img = NULL;
2139 #endif
2141 #ifdef HAVE_NTGUI
2142 /* Create a memory device context for IMG on frame F. It stores the
2143 currently selected GDI object into *PREV for future restoration by
2144 image_unget_x_image_or_dc. */
2146 static XImagePtr_or_DC
2147 image_get_x_image_or_dc (struct frame *f, struct image *img, bool mask_p,
2148 HGDIOBJ *prev)
2150 HDC frame_dc = get_frame_dc (f);
2151 XImagePtr_or_DC ximg = CreateCompatibleDC (frame_dc);
2153 release_frame_dc (f, frame_dc);
2154 *prev = SelectObject (ximg, !mask_p ? img->pixmap : img->mask);
2156 return ximg;
2159 static void
2160 image_unget_x_image_or_dc (struct image *img, bool mask_p,
2161 XImagePtr_or_DC ximg, HGDIOBJ prev)
2163 SelectObject (ximg, prev);
2164 DeleteDC (ximg);
2166 #else /* !HAVE_NTGUI */
2167 /* Get the X image for IMG on frame F. The resulting X image data
2168 should be treated as read-only at least on X. */
2170 static XImagePtr
2171 image_get_x_image (struct frame *f, struct image *img, bool mask_p)
2173 #ifdef HAVE_X_WINDOWS
2174 XImagePtr ximg_in_img = !mask_p ? img->ximg : img->mask_img;
2176 if (ximg_in_img)
2177 return ximg_in_img;
2178 else
2179 return XGetImage (FRAME_X_DISPLAY (f), !mask_p ? img->pixmap : img->mask,
2180 0, 0, img->width, img->height, ~0, ZPixmap);
2181 #elif defined (HAVE_NS)
2182 XImagePtr pixmap = !mask_p ? img->pixmap : img->mask;
2184 ns_retain_object (pixmap);
2185 return pixmap;
2186 #endif
2189 static void
2190 image_unget_x_image (struct image *img, bool mask_p, XImagePtr ximg)
2192 #ifdef HAVE_X_WINDOWS
2193 XImagePtr ximg_in_img = !mask_p ? img->ximg : img->mask_img;
2195 if (ximg_in_img)
2196 eassert (ximg == ximg_in_img);
2197 else
2198 XDestroyImage (ximg);
2199 #elif defined (HAVE_NS)
2200 ns_release_object (ximg);
2201 #endif
2203 #endif /* !HAVE_NTGUI */
2206 /***********************************************************************
2207 File Handling
2208 ***********************************************************************/
2210 /* Find image file FILE. Look in data-directory/images, then
2211 x-bitmap-file-path. Value is the encoded full name of the file
2212 found, or nil if not found. */
2214 Lisp_Object
2215 x_find_image_file (Lisp_Object file)
2217 Lisp_Object file_found, search_path;
2218 int fd;
2220 /* TODO I think this should use something like image-load-path
2221 instead. Unfortunately, that can contain non-string elements. */
2222 search_path = Fcons (Fexpand_file_name (build_string ("images"),
2223 Vdata_directory),
2224 Vx_bitmap_file_path);
2226 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
2227 fd = openp (search_path, file, Qnil, &file_found, Qnil, false);
2229 if (fd == -1)
2230 file_found = Qnil;
2231 else
2233 file_found = ENCODE_FILE (file_found);
2234 if (fd != -2)
2235 emacs_close (fd);
2238 return file_found;
2242 /* Read FILE into memory. Value is a pointer to a buffer allocated
2243 with xmalloc holding FILE's contents. Value is null if an error
2244 occurred. *SIZE is set to the size of the file. */
2246 static unsigned char *
2247 slurp_file (char *file, ptrdiff_t *size)
2249 FILE *fp = emacs_fopen (file, "rb");
2250 unsigned char *buf = NULL;
2251 struct stat st;
2253 if (fp)
2255 ptrdiff_t count = SPECPDL_INDEX ();
2256 record_unwind_protect_ptr (fclose_unwind, fp);
2258 if (fstat (fileno (fp), &st) == 0
2259 && 0 <= st.st_size && st.st_size < min (PTRDIFF_MAX, SIZE_MAX))
2261 /* Report an error if we read past the purported EOF.
2262 This can happen if the file grows as we read it. */
2263 ptrdiff_t buflen = st.st_size;
2264 buf = xmalloc (buflen + 1);
2265 if (fread (buf, 1, buflen + 1, fp) == buflen)
2266 *size = buflen;
2267 else
2269 xfree (buf);
2270 buf = NULL;
2274 unbind_to (count, Qnil);
2277 return buf;
2282 /***********************************************************************
2283 XBM images
2284 ***********************************************************************/
2286 static bool xbm_load (struct frame *f, struct image *img);
2287 static bool xbm_image_p (Lisp_Object object);
2288 static bool xbm_file_p (Lisp_Object);
2291 /* Indices of image specification fields in xbm_format, below. */
2293 enum xbm_keyword_index
2295 XBM_TYPE,
2296 XBM_FILE,
2297 XBM_WIDTH,
2298 XBM_HEIGHT,
2299 XBM_DATA,
2300 XBM_FOREGROUND,
2301 XBM_BACKGROUND,
2302 XBM_ASCENT,
2303 XBM_MARGIN,
2304 XBM_RELIEF,
2305 XBM_ALGORITHM,
2306 XBM_HEURISTIC_MASK,
2307 XBM_MASK,
2308 XBM_LAST
2311 /* Vector of image_keyword structures describing the format
2312 of valid XBM image specifications. */
2314 static const struct image_keyword xbm_format[XBM_LAST] =
2316 {":type", IMAGE_SYMBOL_VALUE, 1},
2317 {":file", IMAGE_STRING_VALUE, 0},
2318 {":width", IMAGE_POSITIVE_INTEGER_VALUE, 0},
2319 {":height", IMAGE_POSITIVE_INTEGER_VALUE, 0},
2320 {":data", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
2321 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
2322 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
2323 {":ascent", IMAGE_ASCENT_VALUE, 0},
2324 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
2325 {":relief", IMAGE_INTEGER_VALUE, 0},
2326 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
2327 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
2328 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
2331 /* Structure describing the image type XBM. */
2333 static struct image_type xbm_type =
2335 XSYMBOL_INIT (Qxbm),
2336 xbm_image_p,
2337 xbm_load,
2338 x_clear_image,
2339 NULL,
2340 NULL
2343 /* Tokens returned from xbm_scan. */
2345 enum xbm_token
2347 XBM_TK_IDENT = 256,
2348 XBM_TK_NUMBER
2352 /* Return true if OBJECT is a valid XBM-type image specification.
2353 A valid specification is a list starting with the symbol `image'
2354 The rest of the list is a property list which must contain an
2355 entry `:type xbm'.
2357 If the specification specifies a file to load, it must contain
2358 an entry `:file FILENAME' where FILENAME is a string.
2360 If the specification is for a bitmap loaded from memory it must
2361 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
2362 WIDTH and HEIGHT are integers > 0. DATA may be:
2364 1. a string large enough to hold the bitmap data, i.e. it must
2365 have a size >= (WIDTH + 7) / 8 * HEIGHT
2367 2. a bool-vector of size >= WIDTH * HEIGHT
2369 3. a vector of strings or bool-vectors, one for each line of the
2370 bitmap.
2372 4. a string containing an in-memory XBM file. WIDTH and HEIGHT
2373 may not be specified in this case because they are defined in the
2374 XBM file.
2376 Both the file and data forms may contain the additional entries
2377 `:background COLOR' and `:foreground COLOR'. If not present,
2378 foreground and background of the frame on which the image is
2379 displayed is used. */
2381 static bool
2382 xbm_image_p (Lisp_Object object)
2384 struct image_keyword kw[XBM_LAST];
2386 memcpy (kw, xbm_format, sizeof kw);
2387 if (!parse_image_spec (object, kw, XBM_LAST, Qxbm))
2388 return 0;
2390 eassert (EQ (kw[XBM_TYPE].value, Qxbm));
2392 if (kw[XBM_FILE].count)
2394 if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_DATA].count)
2395 return 0;
2397 else if (kw[XBM_DATA].count && xbm_file_p (kw[XBM_DATA].value))
2399 /* In-memory XBM file. */
2400 if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_FILE].count)
2401 return 0;
2403 else
2405 Lisp_Object data;
2406 int width, height;
2408 /* Entries for `:width', `:height' and `:data' must be present. */
2409 if (!kw[XBM_WIDTH].count
2410 || !kw[XBM_HEIGHT].count
2411 || !kw[XBM_DATA].count)
2412 return 0;
2414 data = kw[XBM_DATA].value;
2415 width = XFASTINT (kw[XBM_WIDTH].value);
2416 height = XFASTINT (kw[XBM_HEIGHT].value);
2418 /* Check type of data, and width and height against contents of
2419 data. */
2420 if (VECTORP (data))
2422 EMACS_INT i;
2424 /* Number of elements of the vector must be >= height. */
2425 if (ASIZE (data) < height)
2426 return 0;
2428 /* Each string or bool-vector in data must be large enough
2429 for one line of the image. */
2430 for (i = 0; i < height; ++i)
2432 Lisp_Object elt = AREF (data, i);
2434 if (STRINGP (elt))
2436 if (SCHARS (elt)
2437 < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR)
2438 return 0;
2440 else if (BOOL_VECTOR_P (elt))
2442 if (bool_vector_size (elt) < width)
2443 return 0;
2445 else
2446 return 0;
2449 else if (STRINGP (data))
2451 if (SCHARS (data)
2452 < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR * height)
2453 return 0;
2455 else if (BOOL_VECTOR_P (data))
2457 if (bool_vector_size (data) / height < width)
2458 return 0;
2460 else
2461 return 0;
2464 return 1;
2468 /* Scan a bitmap file. FP is the stream to read from. Value is
2469 either an enumerator from enum xbm_token, or a character for a
2470 single-character token, or 0 at end of file. If scanning an
2471 identifier, store the lexeme of the identifier in SVAL. If
2472 scanning a number, store its value in *IVAL. */
2474 static int
2475 xbm_scan (unsigned char **s, unsigned char *end, char *sval, int *ival)
2477 unsigned int c;
2479 loop:
2481 /* Skip white space. */
2482 while (*s < end && (c = *(*s)++, c_isspace (c)))
2485 if (*s >= end)
2486 c = 0;
2487 else if (c_isdigit (c))
2489 int value = 0, digit;
2491 if (c == '0' && *s < end)
2493 c = *(*s)++;
2494 if (c == 'x' || c == 'X')
2496 while (*s < end)
2498 c = *(*s)++;
2499 if (c_isdigit (c))
2500 digit = c - '0';
2501 else if (c >= 'a' && c <= 'f')
2502 digit = c - 'a' + 10;
2503 else if (c >= 'A' && c <= 'F')
2504 digit = c - 'A' + 10;
2505 else
2506 break;
2507 value = 16 * value + digit;
2510 else if (c_isdigit (c))
2512 value = c - '0';
2513 while (*s < end
2514 && (c = *(*s)++, c_isdigit (c)))
2515 value = 8 * value + c - '0';
2518 else
2520 value = c - '0';
2521 while (*s < end
2522 && (c = *(*s)++, c_isdigit (c)))
2523 value = 10 * value + c - '0';
2526 if (*s < end)
2527 *s = *s - 1;
2528 *ival = value;
2529 c = XBM_TK_NUMBER;
2531 else if (c_isalpha (c) || c == '_')
2533 *sval++ = c;
2534 while (*s < end
2535 && (c = *(*s)++, (c_isalnum (c) || c == '_')))
2536 *sval++ = c;
2537 *sval = 0;
2538 if (*s < end)
2539 *s = *s - 1;
2540 c = XBM_TK_IDENT;
2542 else if (c == '/' && **s == '*')
2544 /* C-style comment. */
2545 ++*s;
2546 while (**s && (**s != '*' || *(*s + 1) != '/'))
2547 ++*s;
2548 if (**s)
2550 *s += 2;
2551 goto loop;
2555 return c;
2558 #ifdef HAVE_NTGUI
2560 /* Create a Windows bitmap from X bitmap data. */
2561 static HBITMAP
2562 w32_create_pixmap_from_bitmap_data (int width, int height, char *data)
2564 static unsigned char swap_nibble[16]
2565 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
2566 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
2567 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
2568 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
2569 int i, j, w1, w2;
2570 unsigned char *bits, *p;
2571 HBITMAP bmp;
2573 w1 = (width + 7) / 8; /* nb of 8bits elt in X bitmap */
2574 w2 = ((width + 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
2575 bits = alloca (height * w2);
2576 memset (bits, 0, height * w2);
2577 for (i = 0; i < height; i++)
2579 p = bits + i*w2;
2580 for (j = 0; j < w1; j++)
2582 /* Bitswap XBM bytes to match how Windows does things. */
2583 unsigned char c = *data++;
2584 *p++ = (unsigned char)((swap_nibble[c & 0xf] << 4)
2585 | (swap_nibble[(c>>4) & 0xf]));
2588 bmp = CreateBitmap (width, height, 1, 1, (char *) bits);
2590 return bmp;
2593 static void
2594 convert_mono_to_color_image (struct frame *f, struct image *img,
2595 COLORREF foreground, COLORREF background)
2597 HDC hdc, old_img_dc, new_img_dc;
2598 HGDIOBJ old_prev, new_prev;
2599 HBITMAP new_pixmap;
2601 hdc = get_frame_dc (f);
2602 old_img_dc = CreateCompatibleDC (hdc);
2603 new_img_dc = CreateCompatibleDC (hdc);
2604 new_pixmap = CreateCompatibleBitmap (hdc, img->width, img->height);
2605 release_frame_dc (f, hdc);
2606 old_prev = SelectObject (old_img_dc, img->pixmap);
2607 new_prev = SelectObject (new_img_dc, new_pixmap);
2608 /* Windows convention for mono bitmaps is black = background,
2609 white = foreground. */
2610 SetTextColor (new_img_dc, background);
2611 SetBkColor (new_img_dc, foreground);
2613 BitBlt (new_img_dc, 0, 0, img->width, img->height, old_img_dc,
2614 0, 0, SRCCOPY);
2616 SelectObject (old_img_dc, old_prev);
2617 SelectObject (new_img_dc, new_prev);
2618 DeleteDC (old_img_dc);
2619 DeleteDC (new_img_dc);
2620 DeleteObject (img->pixmap);
2621 if (new_pixmap == 0)
2622 fprintf (stderr, "Failed to convert image to color.\n");
2623 else
2624 img->pixmap = new_pixmap;
2627 #define XBM_BIT_SHUFFLE(b) (~(b))
2629 #else
2631 #define XBM_BIT_SHUFFLE(b) (b)
2633 #endif /* HAVE_NTGUI */
2636 static void
2637 Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data,
2638 RGB_PIXEL_COLOR fg, RGB_PIXEL_COLOR bg,
2639 bool non_default_colors)
2641 #ifdef HAVE_NTGUI
2642 img->pixmap
2643 = w32_create_pixmap_from_bitmap_data (img->width, img->height, data);
2645 /* If colors were specified, transfer the bitmap to a color one. */
2646 if (non_default_colors)
2647 convert_mono_to_color_image (f, img, fg, bg);
2649 #elif defined (HAVE_NS)
2650 img->pixmap = ns_image_from_XBM (data, img->width, img->height);
2652 #else
2653 img->pixmap =
2654 (x_check_image_size (0, img->width, img->height)
2655 ? XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
2656 FRAME_X_WINDOW (f),
2657 data,
2658 img->width, img->height,
2659 fg, bg,
2660 DefaultDepthOfScreen (FRAME_X_SCREEN (f)))
2661 : NO_PIXMAP);
2662 #endif /* !HAVE_NTGUI && !HAVE_NS */
2667 /* Replacement for XReadBitmapFileData which isn't available under old
2668 X versions. CONTENTS is a pointer to a buffer to parse; END is the
2669 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
2670 the image. Return in *DATA the bitmap data allocated with xmalloc.
2671 Value is true if successful. DATA null means just test if
2672 CONTENTS looks like an in-memory XBM file. If INHIBIT_IMAGE_ERROR,
2673 inhibit the call to image_error when the image size is invalid (the
2674 bitmap remains unread). */
2676 static bool
2677 xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *end,
2678 int *width, int *height, char **data,
2679 bool inhibit_image_error)
2681 unsigned char *s = contents;
2682 char buffer[BUFSIZ];
2683 bool padding_p = 0;
2684 bool v10 = 0;
2685 int bytes_per_line, i, nbytes;
2686 char *p;
2687 int value;
2688 int LA1;
2690 #define match() \
2691 LA1 = xbm_scan (&s, end, buffer, &value)
2693 #define expect(TOKEN) \
2694 do \
2696 if (LA1 != (TOKEN)) \
2697 goto failure; \
2698 match (); \
2700 while (0)
2702 #define expect_ident(IDENT) \
2703 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
2704 match (); \
2705 else \
2706 goto failure
2708 *width = *height = -1;
2709 if (data)
2710 *data = NULL;
2711 LA1 = xbm_scan (&s, end, buffer, &value);
2713 /* Parse defines for width, height and hot-spots. */
2714 while (LA1 == '#')
2716 match ();
2717 expect_ident ("define");
2718 expect (XBM_TK_IDENT);
2720 if (LA1 == XBM_TK_NUMBER)
2722 char *q = strrchr (buffer, '_');
2723 q = q ? q + 1 : buffer;
2724 if (strcmp (q, "width") == 0)
2725 *width = value;
2726 else if (strcmp (q, "height") == 0)
2727 *height = value;
2729 expect (XBM_TK_NUMBER);
2732 if (!check_image_size (f, *width, *height))
2734 if (!inhibit_image_error)
2735 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
2736 goto failure;
2738 else if (data == NULL)
2739 goto success;
2741 /* Parse bits. Must start with `static'. */
2742 expect_ident ("static");
2743 if (LA1 == XBM_TK_IDENT)
2745 if (strcmp (buffer, "unsigned") == 0)
2747 match ();
2748 expect_ident ("char");
2750 else if (strcmp (buffer, "short") == 0)
2752 match ();
2753 v10 = 1;
2754 if (*width % 16 && *width % 16 < 9)
2755 padding_p = 1;
2757 else if (strcmp (buffer, "char") == 0)
2758 match ();
2759 else
2760 goto failure;
2762 else
2763 goto failure;
2765 expect (XBM_TK_IDENT);
2766 expect ('[');
2767 expect (']');
2768 expect ('=');
2769 expect ('{');
2771 if (! x_check_image_size (0, *width, *height))
2773 if (!inhibit_image_error)
2774 image_error ("Image too large (%dx%d)",
2775 make_number (*width), make_number (*height));
2776 goto failure;
2778 bytes_per_line = (*width + 7) / 8 + padding_p;
2779 nbytes = bytes_per_line * *height;
2780 p = *data = xmalloc (nbytes);
2782 if (v10)
2784 for (i = 0; i < nbytes; i += 2)
2786 int val = value;
2787 expect (XBM_TK_NUMBER);
2789 *p++ = XBM_BIT_SHUFFLE (val);
2790 if (!padding_p || ((i + 2) % bytes_per_line))
2791 *p++ = XBM_BIT_SHUFFLE (value >> 8);
2793 if (LA1 == ',' || LA1 == '}')
2794 match ();
2795 else
2796 goto failure;
2799 else
2801 for (i = 0; i < nbytes; ++i)
2803 int val = value;
2804 expect (XBM_TK_NUMBER);
2806 *p++ = XBM_BIT_SHUFFLE (val);
2808 if (LA1 == ',' || LA1 == '}')
2809 match ();
2810 else
2811 goto failure;
2815 success:
2816 return 1;
2818 failure:
2820 if (data && *data)
2822 xfree (*data);
2823 *data = NULL;
2825 return 0;
2827 #undef match
2828 #undef expect
2829 #undef expect_ident
2833 /* Load XBM image IMG which will be displayed on frame F from buffer
2834 CONTENTS. END is the end of the buffer. Value is true if
2835 successful. */
2837 static bool
2838 xbm_load_image (struct frame *f, struct image *img, unsigned char *contents,
2839 unsigned char *end)
2841 bool rc;
2842 char *data;
2843 bool success_p = 0;
2845 rc = xbm_read_bitmap_data (f, contents, end, &img->width, &img->height,
2846 &data, 0);
2847 if (rc)
2849 unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
2850 unsigned long background = FRAME_BACKGROUND_PIXEL (f);
2851 bool non_default_colors = 0;
2852 Lisp_Object value;
2854 eassert (img->width > 0 && img->height > 0);
2856 /* Get foreground and background colors, maybe allocate colors. */
2857 value = image_spec_value (img->spec, QCforeground, NULL);
2858 if (!NILP (value))
2860 foreground = x_alloc_image_color (f, img, value, foreground);
2861 non_default_colors = 1;
2863 value = image_spec_value (img->spec, QCbackground, NULL);
2864 if (!NILP (value))
2866 background = x_alloc_image_color (f, img, value, background);
2867 img->background = background;
2868 img->background_valid = 1;
2869 non_default_colors = 1;
2872 Create_Pixmap_From_Bitmap_Data (f, img, data,
2873 foreground, background,
2874 non_default_colors);
2875 xfree (data);
2877 if (img->pixmap == NO_PIXMAP)
2879 x_clear_image (f, img);
2880 image_error ("Unable to create X pixmap for `%s'", img->spec, Qnil);
2882 else
2883 success_p = 1;
2885 else
2886 image_error ("Error loading XBM image `%s'", img->spec, Qnil);
2888 return success_p;
2892 /* Value is true if DATA looks like an in-memory XBM file. */
2894 static bool
2895 xbm_file_p (Lisp_Object data)
2897 int w, h;
2898 return (STRINGP (data)
2899 && xbm_read_bitmap_data (NULL, SDATA (data),
2900 (SDATA (data) + SBYTES (data)),
2901 &w, &h, NULL, 1));
2905 /* Fill image IMG which is used on frame F with pixmap data. Value is
2906 true if successful. */
2908 static bool
2909 xbm_load (struct frame *f, struct image *img)
2911 bool success_p = 0;
2912 Lisp_Object file_name;
2914 eassert (xbm_image_p (img->spec));
2916 /* If IMG->spec specifies a file name, create a non-file spec from it. */
2917 file_name = image_spec_value (img->spec, QCfile, NULL);
2918 if (STRINGP (file_name))
2920 Lisp_Object file;
2921 unsigned char *contents;
2922 ptrdiff_t size;
2924 file = x_find_image_file (file_name);
2925 if (!STRINGP (file))
2927 image_error ("Cannot find image file `%s'", file_name, Qnil);
2928 return 0;
2931 contents = slurp_file (SSDATA (file), &size);
2932 if (contents == NULL)
2934 image_error ("Error loading XBM image `%s'", img->spec, Qnil);
2935 return 0;
2938 success_p = xbm_load_image (f, img, contents, contents + size);
2939 xfree (contents);
2941 else
2943 struct image_keyword fmt[XBM_LAST];
2944 Lisp_Object data;
2945 unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
2946 unsigned long background = FRAME_BACKGROUND_PIXEL (f);
2947 bool non_default_colors = 0;
2948 char *bits;
2949 bool parsed_p;
2950 bool in_memory_file_p = 0;
2952 /* See if data looks like an in-memory XBM file. */
2953 data = image_spec_value (img->spec, QCdata, NULL);
2954 in_memory_file_p = xbm_file_p (data);
2956 /* Parse the image specification. */
2957 memcpy (fmt, xbm_format, sizeof fmt);
2958 parsed_p = parse_image_spec (img->spec, fmt, XBM_LAST, Qxbm);
2959 eassert (parsed_p);
2961 /* Get specified width, and height. */
2962 if (!in_memory_file_p)
2964 img->width = XFASTINT (fmt[XBM_WIDTH].value);
2965 img->height = XFASTINT (fmt[XBM_HEIGHT].value);
2966 eassert (img->width > 0 && img->height > 0);
2967 if (!check_image_size (f, img->width, img->height))
2969 image_error ("Invalid image size (see `max-image-size')",
2970 Qnil, Qnil);
2971 return 0;
2975 /* Get foreground and background colors, maybe allocate colors. */
2976 if (fmt[XBM_FOREGROUND].count
2977 && STRINGP (fmt[XBM_FOREGROUND].value))
2979 foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value,
2980 foreground);
2981 non_default_colors = 1;
2984 if (fmt[XBM_BACKGROUND].count
2985 && STRINGP (fmt[XBM_BACKGROUND].value))
2987 background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value,
2988 background);
2989 non_default_colors = 1;
2992 if (in_memory_file_p)
2993 success_p = xbm_load_image (f, img, SDATA (data),
2994 (SDATA (data)
2995 + SBYTES (data)));
2996 else
2998 USE_SAFE_ALLOCA;
3000 if (VECTORP (data))
3002 int i;
3003 char *p;
3004 int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
3006 SAFE_NALLOCA (bits, nbytes, img->height);
3007 p = bits;
3008 for (i = 0; i < img->height; ++i, p += nbytes)
3010 Lisp_Object line = AREF (data, i);
3011 if (STRINGP (line))
3012 memcpy (p, SDATA (line), nbytes);
3013 else
3014 memcpy (p, bool_vector_data (line), nbytes);
3017 else if (STRINGP (data))
3018 bits = SSDATA (data);
3019 else
3020 bits = (char *) bool_vector_data (data);
3022 #ifdef HAVE_NTGUI
3024 char *invertedBits;
3025 int nbytes, i;
3026 /* Windows mono bitmaps are reversed compared with X. */
3027 invertedBits = bits;
3028 nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
3029 SAFE_NALLOCA (bits, nbytes, img->height);
3030 for (i = 0; i < nbytes; i++)
3031 bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]);
3033 #endif
3034 /* Create the pixmap. */
3036 if (x_check_image_size (0, img->width, img->height))
3037 Create_Pixmap_From_Bitmap_Data (f, img, bits,
3038 foreground, background,
3039 non_default_colors);
3040 else
3041 img->pixmap = NO_PIXMAP;
3043 if (img->pixmap)
3044 success_p = 1;
3045 else
3047 image_error ("Unable to create pixmap for XBM image `%s'",
3048 img->spec, Qnil);
3049 x_clear_image (f, img);
3052 SAFE_FREE ();
3056 return success_p;
3061 /***********************************************************************
3062 XPM images
3063 ***********************************************************************/
3065 #if defined (HAVE_XPM) || defined (HAVE_NS)
3067 static bool xpm_image_p (Lisp_Object object);
3068 static bool xpm_load (struct frame *f, struct image *img);
3070 #endif /* HAVE_XPM || HAVE_NS */
3072 #ifdef HAVE_XPM
3073 #ifdef HAVE_NTGUI
3074 /* Indicate to xpm.h that we don't have Xlib. */
3075 #define FOR_MSW
3076 /* simx.h in xpm defines XColor and XImage differently than Emacs. */
3077 /* It also defines Display the same way as Emacs, but gcc 3.3 still barfs. */
3078 #define XColor xpm_XColor
3079 #define XImage xpm_XImage
3080 #define Display xpm_Display
3081 #define PIXEL_ALREADY_TYPEDEFED
3082 #include "X11/xpm.h"
3083 #undef FOR_MSW
3084 #undef XColor
3085 #undef XImage
3086 #undef Display
3087 #undef PIXEL_ALREADY_TYPEDEFED
3088 #else
3089 #include "X11/xpm.h"
3090 #endif /* HAVE_NTGUI */
3091 #endif /* HAVE_XPM */
3093 #if defined (HAVE_XPM) || defined (HAVE_NS)
3095 /* Indices of image specification fields in xpm_format, below. */
3097 enum xpm_keyword_index
3099 XPM_TYPE,
3100 XPM_FILE,
3101 XPM_DATA,
3102 XPM_ASCENT,
3103 XPM_MARGIN,
3104 XPM_RELIEF,
3105 XPM_ALGORITHM,
3106 XPM_HEURISTIC_MASK,
3107 XPM_MASK,
3108 XPM_COLOR_SYMBOLS,
3109 XPM_BACKGROUND,
3110 XPM_LAST
3113 /* Vector of image_keyword structures describing the format
3114 of valid XPM image specifications. */
3116 static const struct image_keyword xpm_format[XPM_LAST] =
3118 {":type", IMAGE_SYMBOL_VALUE, 1},
3119 {":file", IMAGE_STRING_VALUE, 0},
3120 {":data", IMAGE_STRING_VALUE, 0},
3121 {":ascent", IMAGE_ASCENT_VALUE, 0},
3122 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
3123 {":relief", IMAGE_INTEGER_VALUE, 0},
3124 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3125 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3126 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3127 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3128 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
3131 #if defined HAVE_NTGUI && defined WINDOWSNT
3132 static bool init_xpm_functions (void);
3133 #else
3134 #define init_xpm_functions NULL
3135 #endif
3137 /* Structure describing the image type XPM. */
3139 static struct image_type xpm_type =
3141 XSYMBOL_INIT (Qxpm),
3142 xpm_image_p,
3143 xpm_load,
3144 x_clear_image,
3145 init_xpm_functions,
3146 NULL
3149 #ifdef HAVE_X_WINDOWS
3151 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
3152 functions for allocating image colors. Our own functions handle
3153 color allocation failures more gracefully than the ones on the XPM
3154 lib. */
3156 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
3157 #define ALLOC_XPM_COLORS
3158 #endif
3159 #endif /* HAVE_X_WINDOWS */
3161 #ifdef ALLOC_XPM_COLORS
3163 static struct xpm_cached_color *xpm_cache_color (struct frame *, char *,
3164 XColor *, int);
3166 /* An entry in a hash table used to cache color definitions of named
3167 colors. This cache is necessary to speed up XPM image loading in
3168 case we do color allocations ourselves. Without it, we would need
3169 a call to XParseColor per pixel in the image. */
3171 struct xpm_cached_color
3173 /* Next in collision chain. */
3174 struct xpm_cached_color *next;
3176 /* Color definition (RGB and pixel color). */
3177 XColor color;
3179 /* Color name. */
3180 char name[FLEXIBLE_ARRAY_MEMBER];
3183 /* The hash table used for the color cache, and its bucket vector
3184 size. */
3186 #define XPM_COLOR_CACHE_BUCKETS 1001
3187 static struct xpm_cached_color **xpm_color_cache;
3189 /* Initialize the color cache. */
3191 static void
3192 xpm_init_color_cache (struct frame *f, XpmAttributes *attrs)
3194 size_t nbytes = XPM_COLOR_CACHE_BUCKETS * sizeof *xpm_color_cache;
3195 xpm_color_cache = xzalloc (nbytes);
3196 init_color_table ();
3198 if (attrs->valuemask & XpmColorSymbols)
3200 int i;
3201 XColor color;
3203 for (i = 0; i < attrs->numsymbols; ++i)
3204 if (XParseColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
3205 attrs->colorsymbols[i].value, &color))
3207 color.pixel = lookup_rgb_color (f, color.red, color.green,
3208 color.blue);
3209 xpm_cache_color (f, attrs->colorsymbols[i].name, &color, -1);
3214 /* Free the color cache. */
3216 static void
3217 xpm_free_color_cache (void)
3219 struct xpm_cached_color *p, *next;
3220 int i;
3222 for (i = 0; i < XPM_COLOR_CACHE_BUCKETS; ++i)
3223 for (p = xpm_color_cache[i]; p; p = next)
3225 next = p->next;
3226 xfree (p);
3229 xfree (xpm_color_cache);
3230 xpm_color_cache = NULL;
3231 free_color_table ();
3234 /* Return the bucket index for color named COLOR_NAME in the color
3235 cache. */
3237 static int
3238 xpm_color_bucket (char *color_name)
3240 EMACS_UINT hash = hash_string (color_name, strlen (color_name));
3241 return hash % XPM_COLOR_CACHE_BUCKETS;
3245 /* On frame F, cache values COLOR for color with name COLOR_NAME.
3246 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
3247 entry added. */
3249 static struct xpm_cached_color *
3250 xpm_cache_color (struct frame *f, char *color_name, XColor *color, int bucket)
3252 size_t nbytes;
3253 struct xpm_cached_color *p;
3255 if (bucket < 0)
3256 bucket = xpm_color_bucket (color_name);
3258 nbytes = offsetof (struct xpm_cached_color, name) + strlen (color_name) + 1;
3259 p = xmalloc (nbytes);
3260 strcpy (p->name, color_name);
3261 p->color = *color;
3262 p->next = xpm_color_cache[bucket];
3263 xpm_color_cache[bucket] = p;
3264 return p;
3267 /* Look up color COLOR_NAME for frame F in the color cache. If found,
3268 return the cached definition in *COLOR. Otherwise, make a new
3269 entry in the cache and allocate the color. Value is false if color
3270 allocation failed. */
3272 static bool
3273 xpm_lookup_color (struct frame *f, char *color_name, XColor *color)
3275 struct xpm_cached_color *p;
3276 int h = xpm_color_bucket (color_name);
3278 for (p = xpm_color_cache[h]; p; p = p->next)
3279 if (strcmp (p->name, color_name) == 0)
3280 break;
3282 if (p != NULL)
3283 *color = p->color;
3284 else if (XParseColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
3285 color_name, color))
3287 color->pixel = lookup_rgb_color (f, color->red, color->green,
3288 color->blue);
3289 p = xpm_cache_color (f, color_name, color, h);
3291 /* You get `opaque' at least from ImageMagick converting pbm to xpm
3292 with transparency, and it's useful. */
3293 else if (strcmp ("opaque", color_name) == 0)
3295 memset (color, 0, sizeof (XColor)); /* Is this necessary/correct? */
3296 color->pixel = FRAME_FOREGROUND_PIXEL (f);
3297 p = xpm_cache_color (f, color_name, color, h);
3300 return p != NULL;
3304 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
3305 CLOSURE is a pointer to the frame on which we allocate the
3306 color. Return in *COLOR the allocated color. Value is non-zero
3307 if successful. */
3309 static int
3310 xpm_alloc_color (Display *dpy, Colormap cmap, char *color_name, XColor *color,
3311 void *closure)
3313 return xpm_lookup_color (closure, color_name, color);
3317 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
3318 is a pointer to the frame on which we allocate the color. Value is
3319 non-zero if successful. */
3321 static int
3322 xpm_free_colors (Display *dpy, Colormap cmap, Pixel *pixels, int npixels, void *closure)
3324 return 1;
3327 #endif /* ALLOC_XPM_COLORS */
3330 #ifdef WINDOWSNT
3332 /* XPM library details. */
3334 DEF_DLL_FN (void, XpmFreeAttributes, (XpmAttributes *));
3335 DEF_DLL_FN (int, XpmCreateImageFromBuffer,
3336 (Display *, char *, xpm_XImage **,
3337 xpm_XImage **, XpmAttributes *));
3338 DEF_DLL_FN (int, XpmReadFileToImage,
3339 (Display *, char *, xpm_XImage **,
3340 xpm_XImage **, XpmAttributes *));
3341 DEF_DLL_FN (void, XImageFree, (xpm_XImage *));
3343 static bool
3344 init_xpm_functions (void)
3346 HMODULE library;
3348 if (!(library = w32_delayed_load (Qxpm)))
3349 return 0;
3351 LOAD_DLL_FN (library, XpmFreeAttributes);
3352 LOAD_DLL_FN (library, XpmCreateImageFromBuffer);
3353 LOAD_DLL_FN (library, XpmReadFileToImage);
3354 LOAD_DLL_FN (library, XImageFree);
3355 return 1;
3358 # undef XImageFree
3359 # undef XpmCreateImageFromBuffer
3360 # undef XpmFreeAttributes
3361 # undef XpmReadFileToImage
3363 # define XImageFree fn_XImageFree
3364 # define XpmCreateImageFromBuffer fn_XpmCreateImageFromBuffer
3365 # define XpmFreeAttributes fn_XpmFreeAttributes
3366 # define XpmReadFileToImage fn_XpmReadFileToImage
3368 #endif /* WINDOWSNT */
3370 /* Value is true if COLOR_SYMBOLS is a valid color symbols list
3371 for XPM images. Such a list must consist of conses whose car and
3372 cdr are strings. */
3374 static bool
3375 xpm_valid_color_symbols_p (Lisp_Object color_symbols)
3377 while (CONSP (color_symbols))
3379 Lisp_Object sym = XCAR (color_symbols);
3380 if (!CONSP (sym)
3381 || !STRINGP (XCAR (sym))
3382 || !STRINGP (XCDR (sym)))
3383 break;
3384 color_symbols = XCDR (color_symbols);
3387 return NILP (color_symbols);
3391 /* Value is true if OBJECT is a valid XPM image specification. */
3393 static bool
3394 xpm_image_p (Lisp_Object object)
3396 struct image_keyword fmt[XPM_LAST];
3397 memcpy (fmt, xpm_format, sizeof fmt);
3398 return (parse_image_spec (object, fmt, XPM_LAST, Qxpm)
3399 /* Either `:file' or `:data' must be present. */
3400 && fmt[XPM_FILE].count + fmt[XPM_DATA].count == 1
3401 /* Either no `:color-symbols' or it's a list of conses
3402 whose car and cdr are strings. */
3403 && (fmt[XPM_COLOR_SYMBOLS].count == 0
3404 || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
3407 #endif /* HAVE_XPM || HAVE_NS */
3409 #if defined HAVE_XPM && defined HAVE_X_WINDOWS && !defined USE_GTK
3410 ptrdiff_t
3411 x_create_bitmap_from_xpm_data (struct frame *f, const char **bits)
3413 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
3414 ptrdiff_t id;
3415 int rc;
3416 XpmAttributes attrs;
3417 Pixmap bitmap, mask;
3419 memset (&attrs, 0, sizeof attrs);
3421 attrs.visual = FRAME_X_VISUAL (f);
3422 attrs.colormap = FRAME_X_COLORMAP (f);
3423 attrs.valuemask |= XpmVisual;
3424 attrs.valuemask |= XpmColormap;
3426 rc = XpmCreatePixmapFromData (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3427 (char **) bits, &bitmap, &mask, &attrs);
3428 if (rc != XpmSuccess)
3430 XpmFreeAttributes (&attrs);
3431 return -1;
3434 id = x_allocate_bitmap_record (f);
3435 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
3436 dpyinfo->bitmaps[id - 1].have_mask = true;
3437 dpyinfo->bitmaps[id - 1].mask = mask;
3438 dpyinfo->bitmaps[id - 1].file = NULL;
3439 dpyinfo->bitmaps[id - 1].height = attrs.height;
3440 dpyinfo->bitmaps[id - 1].width = attrs.width;
3441 dpyinfo->bitmaps[id - 1].depth = attrs.depth;
3442 dpyinfo->bitmaps[id - 1].refcount = 1;
3444 XpmFreeAttributes (&attrs);
3445 return id;
3447 #endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */
3449 /* Load image IMG which will be displayed on frame F. Value is
3450 true if successful. */
3452 #ifdef HAVE_XPM
3454 static bool
3455 xpm_load (struct frame *f, struct image *img)
3457 int rc;
3458 XpmAttributes attrs;
3459 Lisp_Object specified_file, color_symbols;
3460 USE_SAFE_ALLOCA;
3462 #ifdef HAVE_NTGUI
3463 HDC hdc;
3464 xpm_XImage * xpm_image = NULL, * xpm_mask = NULL;
3465 #endif /* HAVE_NTGUI */
3467 /* Configure the XPM lib. Use the visual of frame F. Allocate
3468 close colors. Return colors allocated. */
3469 memset (&attrs, 0, sizeof attrs);
3471 #ifndef HAVE_NTGUI
3472 attrs.visual = FRAME_X_VISUAL (f);
3473 attrs.colormap = FRAME_X_COLORMAP (f);
3474 attrs.valuemask |= XpmVisual;
3475 attrs.valuemask |= XpmColormap;
3476 #endif /* HAVE_NTGUI */
3478 #ifdef ALLOC_XPM_COLORS
3479 /* Allocate colors with our own functions which handle
3480 failing color allocation more gracefully. */
3481 attrs.color_closure = f;
3482 attrs.alloc_color = xpm_alloc_color;
3483 attrs.free_colors = xpm_free_colors;
3484 attrs.valuemask |= XpmAllocColor | XpmFreeColors | XpmColorClosure;
3485 #else /* not ALLOC_XPM_COLORS */
3486 /* Let the XPM lib allocate colors. */
3487 attrs.valuemask |= XpmReturnAllocPixels;
3488 #ifdef XpmAllocCloseColors
3489 attrs.alloc_close_colors = 1;
3490 attrs.valuemask |= XpmAllocCloseColors;
3491 #else /* not XpmAllocCloseColors */
3492 attrs.closeness = 600;
3493 attrs.valuemask |= XpmCloseness;
3494 #endif /* not XpmAllocCloseColors */
3495 #endif /* ALLOC_XPM_COLORS */
3497 /* If image specification contains symbolic color definitions, add
3498 these to `attrs'. */
3499 color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL);
3500 if (CONSP (color_symbols))
3502 Lisp_Object tail;
3503 XpmColorSymbol *xpm_syms;
3504 ptrdiff_t i, size;
3506 attrs.valuemask |= XpmColorSymbols;
3508 /* Count number of symbols. */
3509 attrs.numsymbols = 0;
3510 for (tail = color_symbols; CONSP (tail); tail = XCDR (tail))
3511 ++attrs.numsymbols;
3513 /* Allocate an XpmColorSymbol array. */
3514 SAFE_NALLOCA (xpm_syms, 1, attrs.numsymbols);
3515 size = attrs.numsymbols * sizeof *xpm_syms;
3516 memset (xpm_syms, 0, size);
3517 attrs.colorsymbols = xpm_syms;
3519 /* Fill the color symbol array. */
3520 for (tail = color_symbols, i = 0;
3521 CONSP (tail);
3522 ++i, tail = XCDR (tail))
3524 Lisp_Object name;
3525 Lisp_Object color;
3526 char *empty_string = (char *) "";
3528 if (!CONSP (XCAR (tail)))
3530 xpm_syms[i].name = empty_string;
3531 xpm_syms[i].value = empty_string;
3532 continue;
3534 name = XCAR (XCAR (tail));
3535 color = XCDR (XCAR (tail));
3536 if (STRINGP (name))
3537 SAFE_ALLOCA_STRING (xpm_syms[i].name, name);
3538 else
3539 xpm_syms[i].name = empty_string;
3540 if (STRINGP (color))
3541 SAFE_ALLOCA_STRING (xpm_syms[i].value, color);
3542 else
3543 xpm_syms[i].value = empty_string;
3547 /* Create a pixmap for the image, either from a file, or from a
3548 string buffer containing data in the same format as an XPM file. */
3549 #ifdef ALLOC_XPM_COLORS
3550 xpm_init_color_cache (f, &attrs);
3551 #endif
3553 specified_file = image_spec_value (img->spec, QCfile, NULL);
3555 #ifdef HAVE_NTGUI
3557 HDC frame_dc = get_frame_dc (f);
3558 hdc = CreateCompatibleDC (frame_dc);
3559 release_frame_dc (f, frame_dc);
3561 #endif /* HAVE_NTGUI */
3563 if (STRINGP (specified_file))
3565 Lisp_Object file = x_find_image_file (specified_file);
3566 if (!STRINGP (file))
3568 image_error ("Cannot find image file `%s'", specified_file, Qnil);
3569 #ifdef ALLOC_XPM_COLORS
3570 xpm_free_color_cache ();
3571 #endif
3572 SAFE_FREE ();
3573 return 0;
3576 #ifdef HAVE_NTGUI
3577 #ifdef WINDOWSNT
3578 /* FILE is encoded in UTF-8, but image libraries on Windows
3579 support neither UTF-8 nor UTF-16 encoded file names. So we
3580 need to re-encode it in ANSI. */
3581 file = ansi_encode_filename (file);
3582 #endif
3583 /* XpmReadFileToPixmap is not available in the Windows port of
3584 libxpm. But XpmReadFileToImage almost does what we want. */
3585 rc = XpmReadFileToImage (&hdc, SDATA (file),
3586 &xpm_image, &xpm_mask,
3587 &attrs);
3588 #else
3589 rc = XpmReadFileToImage (FRAME_X_DISPLAY (f), SSDATA (file),
3590 &img->ximg, &img->mask_img,
3591 &attrs);
3592 #endif /* HAVE_NTGUI */
3594 else
3596 Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);
3597 if (!STRINGP (buffer))
3599 image_error ("Invalid image data `%s'", buffer, Qnil);
3600 #ifdef ALLOC_XPM_COLORS
3601 xpm_free_color_cache ();
3602 #endif
3603 SAFE_FREE ();
3604 return 0;
3606 #ifdef HAVE_NTGUI
3607 /* XpmCreatePixmapFromBuffer is not available in the Windows port
3608 of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
3609 rc = XpmCreateImageFromBuffer (&hdc, SDATA (buffer),
3610 &xpm_image, &xpm_mask,
3611 &attrs);
3612 #else
3613 rc = XpmCreateImageFromBuffer (FRAME_X_DISPLAY (f), SSDATA (buffer),
3614 &img->ximg, &img->mask_img,
3615 &attrs);
3616 #endif /* HAVE_NTGUI */
3619 #ifdef HAVE_X_WINDOWS
3620 if (rc == XpmSuccess)
3622 img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3623 img->ximg->width, img->ximg->height,
3624 img->ximg->depth);
3625 if (img->pixmap == NO_PIXMAP)
3627 x_clear_image (f, img);
3628 rc = XpmNoMemory;
3630 else if (img->mask_img)
3632 img->mask = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3633 img->mask_img->width,
3634 img->mask_img->height,
3635 img->mask_img->depth);
3636 if (img->mask == NO_PIXMAP)
3638 x_clear_image (f, img);
3639 rc = XpmNoMemory;
3643 #endif
3645 if (rc == XpmSuccess)
3647 #if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS)
3648 img->colors = colors_in_color_table (&img->ncolors);
3649 #else /* not ALLOC_XPM_COLORS */
3650 int i;
3652 #ifdef HAVE_NTGUI
3653 /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
3654 plus some duplicate attributes. */
3655 if (xpm_image && xpm_image->bitmap)
3657 img->pixmap = xpm_image->bitmap;
3658 /* XImageFree in libXpm frees XImage struct without destroying
3659 the bitmap, which is what we want. */
3660 XImageFree (xpm_image);
3662 if (xpm_mask && xpm_mask->bitmap)
3664 /* The mask appears to be inverted compared with what we expect.
3665 TODO: invert our expectations. See other places where we
3666 have to invert bits because our idea of masks is backwards. */
3667 HGDIOBJ old_obj;
3668 old_obj = SelectObject (hdc, xpm_mask->bitmap);
3670 PatBlt (hdc, 0, 0, xpm_mask->width, xpm_mask->height, DSTINVERT);
3671 SelectObject (hdc, old_obj);
3673 img->mask = xpm_mask->bitmap;
3674 XImageFree (xpm_mask);
3675 DeleteDC (hdc);
3678 DeleteDC (hdc);
3679 #endif /* HAVE_NTGUI */
3681 /* Remember allocated colors. */
3682 img->colors = xnmalloc (attrs.nalloc_pixels, sizeof *img->colors);
3683 img->ncolors = attrs.nalloc_pixels;
3684 for (i = 0; i < attrs.nalloc_pixels; ++i)
3686 img->colors[i] = attrs.alloc_pixels[i];
3687 #ifdef DEBUG_X_COLORS
3688 register_color (img->colors[i]);
3689 #endif
3691 #endif /* not ALLOC_XPM_COLORS */
3693 img->width = attrs.width;
3694 img->height = attrs.height;
3695 eassert (img->width > 0 && img->height > 0);
3697 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
3698 XpmFreeAttributes (&attrs);
3700 #ifdef HAVE_X_WINDOWS
3701 /* Maybe fill in the background field while we have ximg handy. */
3702 IMAGE_BACKGROUND (img, f, img->ximg);
3703 if (img->mask_img)
3704 /* Fill in the background_transparent field while we have the
3705 mask handy. */
3706 image_background_transparent (img, f, img->mask_img);
3707 #endif
3709 else
3711 #ifdef HAVE_NTGUI
3712 DeleteDC (hdc);
3713 #endif /* HAVE_NTGUI */
3715 switch (rc)
3717 case XpmOpenFailed:
3718 image_error ("Error opening XPM file (%s)", img->spec, Qnil);
3719 break;
3721 case XpmFileInvalid:
3722 image_error ("Invalid XPM file (%s)", img->spec, Qnil);
3723 break;
3725 case XpmNoMemory:
3726 image_error ("Out of memory (%s)", img->spec, Qnil);
3727 break;
3729 case XpmColorFailed:
3730 image_error ("Color allocation error (%s)", img->spec, Qnil);
3731 break;
3733 default:
3734 image_error ("Unknown error (%s)", img->spec, Qnil);
3735 break;
3739 #ifdef ALLOC_XPM_COLORS
3740 xpm_free_color_cache ();
3741 #endif
3742 SAFE_FREE ();
3743 return rc == XpmSuccess;
3746 #endif /* HAVE_XPM */
3748 #if defined (HAVE_NS) && !defined (HAVE_XPM)
3750 /* XPM support functions for NS where libxpm is not available.
3751 Only XPM version 3 (without any extensions) is supported. */
3753 static void xpm_put_color_table_v (Lisp_Object, const unsigned char *,
3754 int, Lisp_Object);
3755 static Lisp_Object xpm_get_color_table_v (Lisp_Object,
3756 const unsigned char *, int);
3757 static void xpm_put_color_table_h (Lisp_Object, const unsigned char *,
3758 int, Lisp_Object);
3759 static Lisp_Object xpm_get_color_table_h (Lisp_Object,
3760 const unsigned char *, int);
3762 /* Tokens returned from xpm_scan. */
3764 enum xpm_token
3766 XPM_TK_IDENT = 256,
3767 XPM_TK_STRING,
3768 XPM_TK_EOF
3771 /* Scan an XPM data and return a character (< 256) or a token defined
3772 by enum xpm_token above. *S and END are the start (inclusive) and
3773 the end (exclusive) addresses of the data, respectively. Advance
3774 *S while scanning. If token is either XPM_TK_IDENT or
3775 XPM_TK_STRING, *BEG and *LEN are set to the start address and the
3776 length of the corresponding token, respectively. */
3778 static int
3779 xpm_scan (const unsigned char **s,
3780 const unsigned char *end,
3781 const unsigned char **beg,
3782 ptrdiff_t *len)
3784 int c;
3786 while (*s < end)
3788 /* Skip white-space. */
3789 while (*s < end && (c = *(*s)++, c_isspace (c)))
3792 /* gnus-pointer.xpm uses '-' in its identifier.
3793 sb-dir-plus.xpm uses '+' in its identifier. */
3794 if (c_isalpha (c) || c == '_' || c == '-' || c == '+')
3796 *beg = *s - 1;
3797 while (*s < end
3798 && (c = **s, c_isalnum (c)
3799 || c == '_' || c == '-' || c == '+'))
3800 ++*s;
3801 *len = *s - *beg;
3802 return XPM_TK_IDENT;
3804 else if (c == '"')
3806 *beg = *s;
3807 while (*s < end && **s != '"')
3808 ++*s;
3809 *len = *s - *beg;
3810 if (*s < end)
3811 ++*s;
3812 return XPM_TK_STRING;
3814 else if (c == '/')
3816 if (*s < end && **s == '*')
3818 /* C-style comment. */
3819 ++*s;
3822 while (*s < end && *(*s)++ != '*')
3825 while (*s < end && **s != '/');
3826 if (*s < end)
3827 ++*s;
3829 else
3830 return c;
3832 else
3833 return c;
3836 return XPM_TK_EOF;
3839 /* Functions for color table lookup in XPM data. A key is a string
3840 specifying the color of each pixel in XPM data. A value is either
3841 an integer that specifies a pixel color, Qt that specifies
3842 transparency, or Qnil for the unspecified color. If the length of
3843 the key string is one, a vector is used as a table. Otherwise, a
3844 hash table is used. */
3846 static Lisp_Object
3847 xpm_make_color_table_v (void (**put_func) (Lisp_Object,
3848 const unsigned char *,
3849 int,
3850 Lisp_Object),
3851 Lisp_Object (**get_func) (Lisp_Object,
3852 const unsigned char *,
3853 int))
3855 *put_func = xpm_put_color_table_v;
3856 *get_func = xpm_get_color_table_v;
3857 return Fmake_vector (make_number (256), Qnil);
3860 static void
3861 xpm_put_color_table_v (Lisp_Object color_table,
3862 const unsigned char *chars_start,
3863 int chars_len,
3864 Lisp_Object color)
3866 ASET (color_table, *chars_start, color);
3869 static Lisp_Object
3870 xpm_get_color_table_v (Lisp_Object color_table,
3871 const unsigned char *chars_start,
3872 int chars_len)
3874 return AREF (color_table, *chars_start);
3877 static Lisp_Object
3878 xpm_make_color_table_h (void (**put_func) (Lisp_Object,
3879 const unsigned char *,
3880 int,
3881 Lisp_Object),
3882 Lisp_Object (**get_func) (Lisp_Object,
3883 const unsigned char *,
3884 int))
3886 *put_func = xpm_put_color_table_h;
3887 *get_func = xpm_get_color_table_h;
3888 return make_hash_table (hashtest_equal, make_number (DEFAULT_HASH_SIZE),
3889 make_float (DEFAULT_REHASH_SIZE),
3890 make_float (DEFAULT_REHASH_THRESHOLD),
3891 Qnil);
3894 static void
3895 xpm_put_color_table_h (Lisp_Object color_table,
3896 const unsigned char *chars_start,
3897 int chars_len,
3898 Lisp_Object color)
3900 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
3901 EMACS_UINT hash_code;
3902 Lisp_Object chars = make_unibyte_string (chars_start, chars_len);
3904 hash_lookup (table, chars, &hash_code);
3905 hash_put (table, chars, color, hash_code);
3908 static Lisp_Object
3909 xpm_get_color_table_h (Lisp_Object color_table,
3910 const unsigned char *chars_start,
3911 int chars_len)
3913 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
3914 ptrdiff_t i =
3915 hash_lookup (table, make_unibyte_string (chars_start, chars_len), NULL);
3917 return i >= 0 ? HASH_VALUE (table, i) : Qnil;
3920 enum xpm_color_key {
3921 XPM_COLOR_KEY_S,
3922 XPM_COLOR_KEY_M,
3923 XPM_COLOR_KEY_G4,
3924 XPM_COLOR_KEY_G,
3925 XPM_COLOR_KEY_C
3928 static const char xpm_color_key_strings[][4] = {"s", "m", "g4", "g", "c"};
3930 static int
3931 xpm_str_to_color_key (const char *s)
3933 int i;
3935 for (i = 0; i < ARRAYELTS (xpm_color_key_strings); i++)
3936 if (strcmp (xpm_color_key_strings[i], s) == 0)
3937 return i;
3938 return -1;
3941 static bool
3942 xpm_load_image (struct frame *f,
3943 struct image *img,
3944 const unsigned char *contents,
3945 const unsigned char *end)
3947 const unsigned char *s = contents, *beg, *str;
3948 unsigned char buffer[BUFSIZ];
3949 int width, height, x, y;
3950 int num_colors, chars_per_pixel;
3951 ptrdiff_t len;
3952 int LA1;
3953 void (*put_color_table) (Lisp_Object, const unsigned char *, int, Lisp_Object);
3954 Lisp_Object (*get_color_table) (Lisp_Object, const unsigned char *, int);
3955 Lisp_Object frame, color_symbols, color_table;
3956 int best_key;
3957 bool have_mask = false;
3958 XImagePtr ximg = NULL, mask_img = NULL;
3960 #define match() \
3961 LA1 = xpm_scan (&s, end, &beg, &len)
3963 #define expect(TOKEN) \
3964 do \
3966 if (LA1 != (TOKEN)) \
3967 goto failure; \
3968 match (); \
3970 while (0)
3972 #define expect_ident(IDENT) \
3973 if (LA1 == XPM_TK_IDENT \
3974 && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
3975 match (); \
3976 else \
3977 goto failure
3979 if (!(end - s >= 9 && memcmp (s, "/* XPM */", 9) == 0))
3980 goto failure;
3981 s += 9;
3982 match ();
3983 expect_ident ("static");
3984 expect_ident ("char");
3985 expect ('*');
3986 expect (XPM_TK_IDENT);
3987 expect ('[');
3988 expect (']');
3989 expect ('=');
3990 expect ('{');
3991 expect (XPM_TK_STRING);
3992 if (len >= BUFSIZ)
3993 goto failure;
3994 memcpy (buffer, beg, len);
3995 buffer[len] = '\0';
3996 if (sscanf (buffer, "%d %d %d %d", &width, &height,
3997 &num_colors, &chars_per_pixel) != 4
3998 || width <= 0 || height <= 0
3999 || num_colors <= 0 || chars_per_pixel <= 0)
4000 goto failure;
4002 if (!check_image_size (f, width, height))
4004 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
4005 goto failure;
4008 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)
4009 #ifndef HAVE_NS
4010 || !image_create_x_image_and_pixmap (f, img, width, height, 1,
4011 &mask_img, 1)
4012 #endif
4015 image_error ("Image too large", Qnil, Qnil);
4016 goto failure;
4019 expect (',');
4021 XSETFRAME (frame, f);
4022 if (!NILP (Fxw_display_color_p (frame)))
4023 best_key = XPM_COLOR_KEY_C;
4024 else if (!NILP (Fx_display_grayscale_p (frame)))
4025 best_key = (XFASTINT (Fx_display_planes (frame)) > 2
4026 ? XPM_COLOR_KEY_G : XPM_COLOR_KEY_G4);
4027 else
4028 best_key = XPM_COLOR_KEY_M;
4030 color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL);
4031 if (chars_per_pixel == 1)
4032 color_table = xpm_make_color_table_v (&put_color_table,
4033 &get_color_table);
4034 else
4035 color_table = xpm_make_color_table_h (&put_color_table,
4036 &get_color_table);
4038 while (num_colors-- > 0)
4040 char *color, *max_color;
4041 int key, next_key, max_key = 0;
4042 Lisp_Object symbol_color = Qnil, color_val;
4043 XColor cdef;
4045 expect (XPM_TK_STRING);
4046 if (len <= chars_per_pixel || len >= BUFSIZ + chars_per_pixel)
4047 goto failure;
4048 memcpy (buffer, beg + chars_per_pixel, len - chars_per_pixel);
4049 buffer[len - chars_per_pixel] = '\0';
4051 str = strtok (buffer, " \t");
4052 if (str == NULL)
4053 goto failure;
4054 key = xpm_str_to_color_key (str);
4055 if (key < 0)
4056 goto failure;
4059 color = strtok (NULL, " \t");
4060 if (color == NULL)
4061 goto failure;
4063 while ((str = strtok (NULL, " \t")) != NULL)
4065 next_key = xpm_str_to_color_key (str);
4066 if (next_key >= 0)
4067 break;
4068 color[strlen (color)] = ' ';
4071 if (key == XPM_COLOR_KEY_S)
4073 if (NILP (symbol_color))
4074 symbol_color = build_string (color);
4076 else if (max_key < key && key <= best_key)
4078 max_key = key;
4079 max_color = color;
4081 key = next_key;
4083 while (str);
4085 color_val = Qnil;
4086 if (!NILP (color_symbols) && !NILP (symbol_color))
4088 Lisp_Object specified_color = Fassoc (symbol_color, color_symbols);
4090 if (CONSP (specified_color) && STRINGP (XCDR (specified_color)))
4092 if (xstrcasecmp (SSDATA (XCDR (specified_color)), "None") == 0)
4093 color_val = Qt;
4094 else if (x_defined_color (f, SSDATA (XCDR (specified_color)),
4095 &cdef, 0))
4096 color_val = make_number (cdef.pixel);
4099 if (NILP (color_val) && max_key > 0)
4101 if (xstrcasecmp (max_color, "None") == 0)
4102 color_val = Qt;
4103 else if (x_defined_color (f, max_color, &cdef, 0))
4104 color_val = make_number (cdef.pixel);
4106 if (!NILP (color_val))
4107 (*put_color_table) (color_table, beg, chars_per_pixel, color_val);
4109 expect (',');
4112 for (y = 0; y < height; y++)
4114 expect (XPM_TK_STRING);
4115 str = beg;
4116 if (len < width * chars_per_pixel)
4117 goto failure;
4118 for (x = 0; x < width; x++, str += chars_per_pixel)
4120 Lisp_Object color_val =
4121 (*get_color_table) (color_table, str, chars_per_pixel);
4123 XPutPixel (ximg, x, y,
4124 (INTEGERP (color_val) ? XINT (color_val)
4125 : FRAME_FOREGROUND_PIXEL (f)));
4126 #ifndef HAVE_NS
4127 XPutPixel (mask_img, x, y,
4128 (!EQ (color_val, Qt) ? PIX_MASK_DRAW
4129 : (have_mask = true, PIX_MASK_RETAIN)));
4130 #else
4131 if (EQ (color_val, Qt))
4132 ns_set_alpha (ximg, x, y, 0);
4133 #endif
4135 if (y + 1 < height)
4136 expect (',');
4139 img->width = width;
4140 img->height = height;
4142 /* Maybe fill in the background field while we have ximg handy. */
4143 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
4144 IMAGE_BACKGROUND (img, f, ximg);
4146 image_put_x_image (f, img, ximg, 0);
4147 #ifndef HAVE_NS
4148 if (have_mask)
4150 /* Fill in the background_transparent field while we have the
4151 mask handy. */
4152 image_background_transparent (img, f, mask_img);
4154 image_put_x_image (f, img, mask_img, 1);
4156 else
4158 x_destroy_x_image (mask_img);
4159 x_clear_image_1 (f, img, CLEAR_IMAGE_MASK);
4161 #endif
4162 return 1;
4164 failure:
4165 image_error ("Invalid XPM file (%s)", img->spec, Qnil);
4166 x_destroy_x_image (ximg);
4167 x_destroy_x_image (mask_img);
4168 x_clear_image (f, img);
4169 return 0;
4171 #undef match
4172 #undef expect
4173 #undef expect_ident
4176 static bool
4177 xpm_load (struct frame *f,
4178 struct image *img)
4180 bool success_p = 0;
4181 Lisp_Object file_name;
4183 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4184 file_name = image_spec_value (img->spec, QCfile, NULL);
4185 if (STRINGP (file_name))
4187 Lisp_Object file;
4188 unsigned char *contents;
4189 ptrdiff_t size;
4191 file = x_find_image_file (file_name);
4192 if (!STRINGP (file))
4194 image_error ("Cannot find image file `%s'", file_name, Qnil);
4195 return 0;
4198 contents = slurp_file (SSDATA (file), &size);
4199 if (contents == NULL)
4201 image_error ("Error loading XPM image `%s'", img->spec, Qnil);
4202 return 0;
4205 success_p = xpm_load_image (f, img, contents, contents + size);
4206 xfree (contents);
4208 else
4210 Lisp_Object data;
4212 data = image_spec_value (img->spec, QCdata, NULL);
4213 if (!STRINGP (data))
4215 image_error ("Invalid image data `%s'", data, Qnil);
4216 return 0;
4218 success_p = xpm_load_image (f, img, SDATA (data),
4219 SDATA (data) + SBYTES (data));
4222 return success_p;
4225 #endif /* HAVE_NS && !HAVE_XPM */
4229 /***********************************************************************
4230 Color table
4231 ***********************************************************************/
4233 #ifdef COLOR_TABLE_SUPPORT
4235 /* An entry in the color table mapping an RGB color to a pixel color. */
4237 struct ct_color
4239 int r, g, b;
4240 unsigned long pixel;
4242 /* Next in color table collision list. */
4243 struct ct_color *next;
4246 /* The bucket vector size to use. Must be prime. */
4248 #define CT_SIZE 101
4250 /* Value is a hash of the RGB color given by R, G, and B. */
4252 static unsigned
4253 ct_hash_rgb (unsigned r, unsigned g, unsigned b)
4255 return (r << 16) ^ (g << 8) ^ b;
4258 /* The color hash table. */
4260 static struct ct_color **ct_table;
4262 /* Number of entries in the color table. */
4264 static int ct_colors_allocated;
4265 enum
4267 ct_colors_allocated_max =
4268 min (INT_MAX,
4269 min (PTRDIFF_MAX, SIZE_MAX) / sizeof (unsigned long))
4272 /* Initialize the color table. */
4274 static void
4275 init_color_table (void)
4277 int size = CT_SIZE * sizeof (*ct_table);
4278 ct_table = xzalloc (size);
4279 ct_colors_allocated = 0;
4283 /* Free memory associated with the color table. */
4285 static void
4286 free_color_table (void)
4288 int i;
4289 struct ct_color *p, *next;
4291 for (i = 0; i < CT_SIZE; ++i)
4292 for (p = ct_table[i]; p; p = next)
4294 next = p->next;
4295 xfree (p);
4298 xfree (ct_table);
4299 ct_table = NULL;
4303 /* Value is a pixel color for RGB color R, G, B on frame F. If an
4304 entry for that color already is in the color table, return the
4305 pixel color of that entry. Otherwise, allocate a new color for R,
4306 G, B, and make an entry in the color table. */
4308 static unsigned long
4309 lookup_rgb_color (struct frame *f, int r, int g, int b)
4311 unsigned hash = ct_hash_rgb (r, g, b);
4312 int i = hash % CT_SIZE;
4313 struct ct_color *p;
4314 Display_Info *dpyinfo;
4316 /* Handle TrueColor visuals specially, which improves performance by
4317 two orders of magnitude. Freeing colors on TrueColor visuals is
4318 a nop, and pixel colors specify RGB values directly. See also
4319 the Xlib spec, chapter 3.1. */
4320 dpyinfo = FRAME_DISPLAY_INFO (f);
4321 if (dpyinfo->red_bits > 0)
4323 unsigned long pr, pg, pb;
4325 /* Apply gamma-correction like normal color allocation does. */
4326 if (f->gamma)
4328 XColor color;
4329 color.red = r, color.green = g, color.blue = b;
4330 gamma_correct (f, &color);
4331 r = color.red, g = color.green, b = color.blue;
4334 /* Scale down RGB values to the visual's bits per RGB, and shift
4335 them to the right position in the pixel color. Note that the
4336 original RGB values are 16-bit values, as usual in X. */
4337 pr = (r >> (16 - dpyinfo->red_bits)) << dpyinfo->red_offset;
4338 pg = (g >> (16 - dpyinfo->green_bits)) << dpyinfo->green_offset;
4339 pb = (b >> (16 - dpyinfo->blue_bits)) << dpyinfo->blue_offset;
4341 /* Assemble the pixel color. */
4342 return pr | pg | pb;
4345 for (p = ct_table[i]; p; p = p->next)
4346 if (p->r == r && p->g == g && p->b == b)
4347 break;
4349 if (p == NULL)
4352 #ifdef HAVE_X_WINDOWS
4353 XColor color;
4354 Colormap cmap;
4355 bool rc;
4356 #else
4357 COLORREF color;
4358 #endif
4360 if (ct_colors_allocated_max <= ct_colors_allocated)
4361 return FRAME_FOREGROUND_PIXEL (f);
4363 #ifdef HAVE_X_WINDOWS
4364 color.red = r;
4365 color.green = g;
4366 color.blue = b;
4368 cmap = FRAME_X_COLORMAP (f);
4369 rc = x_alloc_nearest_color (f, cmap, &color);
4370 if (rc)
4372 ++ct_colors_allocated;
4373 p = xmalloc (sizeof *p);
4374 p->r = r;
4375 p->g = g;
4376 p->b = b;
4377 p->pixel = color.pixel;
4378 p->next = ct_table[i];
4379 ct_table[i] = p;
4381 else
4382 return FRAME_FOREGROUND_PIXEL (f);
4384 #else
4385 #ifdef HAVE_NTGUI
4386 color = PALETTERGB (r, g, b);
4387 #else
4388 color = RGB_TO_ULONG (r, g, b);
4389 #endif /* HAVE_NTGUI */
4390 ++ct_colors_allocated;
4391 p = xmalloc (sizeof *p);
4392 p->r = r;
4393 p->g = g;
4394 p->b = b;
4395 p->pixel = color;
4396 p->next = ct_table[i];
4397 ct_table[i] = p;
4398 #endif /* HAVE_X_WINDOWS */
4402 return p->pixel;
4406 /* Look up pixel color PIXEL which is used on frame F in the color
4407 table. If not already present, allocate it. Value is PIXEL. */
4409 static unsigned long
4410 lookup_pixel_color (struct frame *f, unsigned long pixel)
4412 int i = pixel % CT_SIZE;
4413 struct ct_color *p;
4415 for (p = ct_table[i]; p; p = p->next)
4416 if (p->pixel == pixel)
4417 break;
4419 if (p == NULL)
4421 XColor color;
4422 Colormap cmap;
4423 bool rc;
4425 if (ct_colors_allocated_max <= ct_colors_allocated)
4426 return FRAME_FOREGROUND_PIXEL (f);
4428 #ifdef HAVE_X_WINDOWS
4429 cmap = FRAME_X_COLORMAP (f);
4430 color.pixel = pixel;
4431 x_query_color (f, &color);
4432 rc = x_alloc_nearest_color (f, cmap, &color);
4433 #else
4434 block_input ();
4435 cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f));
4436 color.pixel = pixel;
4437 XQueryColor (NULL, cmap, &color);
4438 rc = x_alloc_nearest_color (f, cmap, &color);
4439 unblock_input ();
4440 #endif /* HAVE_X_WINDOWS */
4442 if (rc)
4444 ++ct_colors_allocated;
4446 p = xmalloc (sizeof *p);
4447 p->r = color.red;
4448 p->g = color.green;
4449 p->b = color.blue;
4450 p->pixel = pixel;
4451 p->next = ct_table[i];
4452 ct_table[i] = p;
4454 else
4455 return FRAME_FOREGROUND_PIXEL (f);
4457 return p->pixel;
4461 /* Value is a vector of all pixel colors contained in the color table,
4462 allocated via xmalloc. Set *N to the number of colors. */
4464 static unsigned long *
4465 colors_in_color_table (int *n)
4467 int i, j;
4468 struct ct_color *p;
4469 unsigned long *colors;
4471 if (ct_colors_allocated == 0)
4473 *n = 0;
4474 colors = NULL;
4476 else
4478 colors = xmalloc (ct_colors_allocated * sizeof *colors);
4479 *n = ct_colors_allocated;
4481 for (i = j = 0; i < CT_SIZE; ++i)
4482 for (p = ct_table[i]; p; p = p->next)
4483 colors[j++] = p->pixel;
4486 return colors;
4489 #else /* COLOR_TABLE_SUPPORT */
4491 static unsigned long
4492 lookup_rgb_color (struct frame *f, int r, int g, int b)
4494 unsigned long pixel;
4496 #ifdef HAVE_NTGUI
4497 pixel = PALETTERGB (r >> 8, g >> 8, b >> 8);
4498 #endif /* HAVE_NTGUI */
4500 #ifdef HAVE_NS
4501 pixel = RGB_TO_ULONG (r >> 8, g >> 8, b >> 8);
4502 #endif /* HAVE_NS */
4503 return pixel;
4506 static void
4507 init_color_table (void)
4510 #endif /* COLOR_TABLE_SUPPORT */
4513 /***********************************************************************
4514 Algorithms
4515 ***********************************************************************/
4517 /* Edge detection matrices for different edge-detection
4518 strategies. */
4520 static int emboss_matrix[9] = {
4521 /* x - 1 x x + 1 */
4522 2, -1, 0, /* y - 1 */
4523 -1, 0, 1, /* y */
4524 0, 1, -2 /* y + 1 */
4527 static int laplace_matrix[9] = {
4528 /* x - 1 x x + 1 */
4529 1, 0, 0, /* y - 1 */
4530 0, 0, 0, /* y */
4531 0, 0, -1 /* y + 1 */
4534 /* Value is the intensity of the color whose red/green/blue values
4535 are R, G, and B. */
4537 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
4540 /* On frame F, return an array of XColor structures describing image
4541 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
4542 means also fill the red/green/blue members of the XColor
4543 structures. Value is a pointer to the array of XColors structures,
4544 allocated with xmalloc; it must be freed by the caller. */
4546 static XColor *
4547 x_to_xcolors (struct frame *f, struct image *img, bool rgb_p)
4549 int x, y;
4550 XColor *colors, *p;
4551 XImagePtr_or_DC ximg;
4552 #ifdef HAVE_NTGUI
4553 HGDIOBJ prev;
4554 #endif /* HAVE_NTGUI */
4556 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *colors / img->width < img->height)
4557 memory_full (SIZE_MAX);
4558 colors = xmalloc (sizeof *colors * img->width * img->height);
4560 /* Get the X image or create a memory device context for IMG. */
4561 ximg = image_get_x_image_or_dc (f, img, 0, &prev);
4563 /* Fill the `pixel' members of the XColor array. I wished there
4564 were an easy and portable way to circumvent XGetPixel. */
4565 p = colors;
4566 for (y = 0; y < img->height; ++y)
4568 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
4569 XColor *row = p;
4570 for (x = 0; x < img->width; ++x, ++p)
4571 p->pixel = GET_PIXEL (ximg, x, y);
4572 if (rgb_p)
4573 x_query_colors (f, row, img->width);
4575 #else
4577 for (x = 0; x < img->width; ++x, ++p)
4579 /* W32_TODO: palette support needed here? */
4580 p->pixel = GET_PIXEL (ximg, x, y);
4581 if (rgb_p)
4583 p->red = RED16_FROM_ULONG (p->pixel);
4584 p->green = GREEN16_FROM_ULONG (p->pixel);
4585 p->blue = BLUE16_FROM_ULONG (p->pixel);
4588 #endif /* HAVE_X_WINDOWS */
4591 image_unget_x_image_or_dc (img, 0, ximg, prev);
4593 return colors;
4596 #ifdef HAVE_NTGUI
4598 /* Put a pixel of COLOR at position X, Y in XIMG. XIMG must have been
4599 created with CreateDIBSection, with the pointer to the bit values
4600 stored in ximg->data. */
4602 static void
4603 XPutPixel (XImagePtr ximg, int x, int y, COLORREF color)
4605 int width = ximg->info.bmiHeader.biWidth;
4606 unsigned char * pixel;
4608 /* True color images. */
4609 if (ximg->info.bmiHeader.biBitCount == 24)
4611 int rowbytes = width * 3;
4612 /* Ensure scanlines are aligned on 4 byte boundaries. */
4613 if (rowbytes % 4)
4614 rowbytes += 4 - (rowbytes % 4);
4616 pixel = ximg->data + y * rowbytes + x * 3;
4617 /* Windows bitmaps are in BGR order. */
4618 *pixel = GetBValue (color);
4619 *(pixel + 1) = GetGValue (color);
4620 *(pixel + 2) = GetRValue (color);
4622 /* Monochrome images. */
4623 else if (ximg->info.bmiHeader.biBitCount == 1)
4625 int rowbytes = width / 8;
4626 /* Ensure scanlines are aligned on 4 byte boundaries. */
4627 if (rowbytes % 4)
4628 rowbytes += 4 - (rowbytes % 4);
4629 pixel = ximg->data + y * rowbytes + x / 8;
4630 /* Filter out palette info. */
4631 if (color & 0x00ffffff)
4632 *pixel = *pixel | (1 << x % 8);
4633 else
4634 *pixel = *pixel & ~(1 << x % 8);
4636 else
4637 image_error ("XPutPixel: palette image not supported", Qnil, Qnil);
4640 #endif /* HAVE_NTGUI */
4642 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
4643 RGB members are set. F is the frame on which this all happens.
4644 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
4646 static void
4647 x_from_xcolors (struct frame *f, struct image *img, XColor *colors)
4649 int x, y;
4650 XImagePtr oimg = NULL;
4651 XColor *p;
4653 init_color_table ();
4655 x_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_COLORS);
4656 image_create_x_image_and_pixmap (f, img, img->width, img->height, 0,
4657 &oimg, 0);
4658 p = colors;
4659 for (y = 0; y < img->height; ++y)
4660 for (x = 0; x < img->width; ++x, ++p)
4662 unsigned long pixel;
4663 pixel = lookup_rgb_color (f, p->red, p->green, p->blue);
4664 XPutPixel (oimg, x, y, pixel);
4667 xfree (colors);
4669 image_put_x_image (f, img, oimg, 0);
4670 #ifdef COLOR_TABLE_SUPPORT
4671 img->colors = colors_in_color_table (&img->ncolors);
4672 free_color_table ();
4673 #endif /* COLOR_TABLE_SUPPORT */
4677 /* On frame F, perform edge-detection on image IMG.
4679 MATRIX is a nine-element array specifying the transformation
4680 matrix. See emboss_matrix for an example.
4682 COLOR_ADJUST is a color adjustment added to each pixel of the
4683 outgoing image. */
4685 static void
4686 x_detect_edges (struct frame *f, struct image *img, int *matrix, int color_adjust)
4688 XColor *colors = x_to_xcolors (f, img, 1);
4689 XColor *new, *p;
4690 int x, y, i, sum;
4692 for (i = sum = 0; i < 9; ++i)
4693 sum += eabs (matrix[i]);
4695 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
4697 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *new / img->width < img->height)
4698 memory_full (SIZE_MAX);
4699 new = xmalloc (sizeof *new * img->width * img->height);
4701 for (y = 0; y < img->height; ++y)
4703 p = COLOR (new, 0, y);
4704 p->red = p->green = p->blue = 0xffff/2;
4705 p = COLOR (new, img->width - 1, y);
4706 p->red = p->green = p->blue = 0xffff/2;
4709 for (x = 1; x < img->width - 1; ++x)
4711 p = COLOR (new, x, 0);
4712 p->red = p->green = p->blue = 0xffff/2;
4713 p = COLOR (new, x, img->height - 1);
4714 p->red = p->green = p->blue = 0xffff/2;
4717 for (y = 1; y < img->height - 1; ++y)
4719 p = COLOR (new, 1, y);
4721 for (x = 1; x < img->width - 1; ++x, ++p)
4723 int r, g, b, yy, xx;
4725 r = g = b = i = 0;
4726 for (yy = y - 1; yy < y + 2; ++yy)
4727 for (xx = x - 1; xx < x + 2; ++xx, ++i)
4728 if (matrix[i])
4730 XColor *t = COLOR (colors, xx, yy);
4731 r += matrix[i] * t->red;
4732 g += matrix[i] * t->green;
4733 b += matrix[i] * t->blue;
4736 r = (r / sum + color_adjust) & 0xffff;
4737 g = (g / sum + color_adjust) & 0xffff;
4738 b = (b / sum + color_adjust) & 0xffff;
4739 p->red = p->green = p->blue = COLOR_INTENSITY (r, g, b);
4743 xfree (colors);
4744 x_from_xcolors (f, img, new);
4746 #undef COLOR
4750 /* Perform the pre-defined `emboss' edge-detection on image IMG
4751 on frame F. */
4753 static void
4754 x_emboss (struct frame *f, struct image *img)
4756 x_detect_edges (f, img, emboss_matrix, 0xffff / 2);
4760 /* Transform image IMG which is used on frame F with a Laplace
4761 edge-detection algorithm. The result is an image that can be used
4762 to draw disabled buttons, for example. */
4764 static void
4765 x_laplace (struct frame *f, struct image *img)
4767 x_detect_edges (f, img, laplace_matrix, 45000);
4771 /* Perform edge-detection on image IMG on frame F, with specified
4772 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
4774 MATRIX must be either
4776 - a list of at least 9 numbers in row-major form
4777 - a vector of at least 9 numbers
4779 COLOR_ADJUST nil means use a default; otherwise it must be a
4780 number. */
4782 static void
4783 x_edge_detection (struct frame *f, struct image *img, Lisp_Object matrix,
4784 Lisp_Object color_adjust)
4786 int i = 0;
4787 int trans[9];
4789 if (CONSP (matrix))
4791 for (i = 0;
4792 i < 9 && CONSP (matrix) && NUMBERP (XCAR (matrix));
4793 ++i, matrix = XCDR (matrix))
4794 trans[i] = XFLOATINT (XCAR (matrix));
4796 else if (VECTORP (matrix) && ASIZE (matrix) >= 9)
4798 for (i = 0; i < 9 && NUMBERP (AREF (matrix, i)); ++i)
4799 trans[i] = XFLOATINT (AREF (matrix, i));
4802 if (NILP (color_adjust))
4803 color_adjust = make_number (0xffff / 2);
4805 if (i == 9 && NUMBERP (color_adjust))
4806 x_detect_edges (f, img, trans, XFLOATINT (color_adjust));
4810 /* Transform image IMG on frame F so that it looks disabled. */
4812 static void
4813 x_disable_image (struct frame *f, struct image *img)
4815 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
4816 #ifdef HAVE_NTGUI
4817 int n_planes = dpyinfo->n_planes * dpyinfo->n_cbits;
4818 #else
4819 int n_planes = dpyinfo->n_planes;
4820 #endif /* HAVE_NTGUI */
4822 if (n_planes >= 2)
4824 /* Color (or grayscale). Convert to gray, and equalize. Just
4825 drawing such images with a stipple can look very odd, so
4826 we're using this method instead. */
4827 XColor *colors = x_to_xcolors (f, img, 1);
4828 XColor *p, *end;
4829 const int h = 15000;
4830 const int l = 30000;
4832 for (p = colors, end = colors + img->width * img->height;
4833 p < end;
4834 ++p)
4836 int i = COLOR_INTENSITY (p->red, p->green, p->blue);
4837 int i2 = (0xffff - h - l) * i / 0xffff + l;
4838 p->red = p->green = p->blue = i2;
4841 x_from_xcolors (f, img, colors);
4844 /* Draw a cross over the disabled image, if we must or if we
4845 should. */
4846 if (n_planes < 2 || cross_disabled_images)
4848 #ifndef HAVE_NTGUI
4849 #ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
4851 #define MaskForeground(f) WHITE_PIX_DEFAULT (f)
4853 Display *dpy = FRAME_X_DISPLAY (f);
4854 GC gc;
4856 image_sync_to_pixmaps (f, img);
4857 gc = XCreateGC (dpy, img->pixmap, 0, NULL);
4858 XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f));
4859 XDrawLine (dpy, img->pixmap, gc, 0, 0,
4860 img->width - 1, img->height - 1);
4861 XDrawLine (dpy, img->pixmap, gc, 0, img->height - 1,
4862 img->width - 1, 0);
4863 XFreeGC (dpy, gc);
4865 if (img->mask)
4867 gc = XCreateGC (dpy, img->mask, 0, NULL);
4868 XSetForeground (dpy, gc, MaskForeground (f));
4869 XDrawLine (dpy, img->mask, gc, 0, 0,
4870 img->width - 1, img->height - 1);
4871 XDrawLine (dpy, img->mask, gc, 0, img->height - 1,
4872 img->width - 1, 0);
4873 XFreeGC (dpy, gc);
4875 #endif /* !HAVE_NS */
4876 #else
4877 HDC hdc, bmpdc;
4878 HGDIOBJ prev;
4880 hdc = get_frame_dc (f);
4881 bmpdc = CreateCompatibleDC (hdc);
4882 release_frame_dc (f, hdc);
4884 prev = SelectObject (bmpdc, img->pixmap);
4886 SetTextColor (bmpdc, BLACK_PIX_DEFAULT (f));
4887 MoveToEx (bmpdc, 0, 0, NULL);
4888 LineTo (bmpdc, img->width - 1, img->height - 1);
4889 MoveToEx (bmpdc, 0, img->height - 1, NULL);
4890 LineTo (bmpdc, img->width - 1, 0);
4892 if (img->mask)
4894 SelectObject (bmpdc, img->mask);
4895 SetTextColor (bmpdc, WHITE_PIX_DEFAULT (f));
4896 MoveToEx (bmpdc, 0, 0, NULL);
4897 LineTo (bmpdc, img->width - 1, img->height - 1);
4898 MoveToEx (bmpdc, 0, img->height - 1, NULL);
4899 LineTo (bmpdc, img->width - 1, 0);
4901 SelectObject (bmpdc, prev);
4902 DeleteDC (bmpdc);
4903 #endif /* HAVE_NTGUI */
4908 /* Build a mask for image IMG which is used on frame F. FILE is the
4909 name of an image file, for error messages. HOW determines how to
4910 determine the background color of IMG. If it is a list '(R G B)',
4911 with R, G, and B being integers >= 0, take that as the color of the
4912 background. Otherwise, determine the background color of IMG
4913 heuristically. */
4915 static void
4916 x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how)
4918 XImagePtr_or_DC ximg;
4919 #ifndef HAVE_NTGUI
4920 XImagePtr mask_img;
4921 #else
4922 HGDIOBJ prev;
4923 char *mask_img;
4924 int row_width;
4925 #endif /* HAVE_NTGUI */
4926 int x, y;
4927 bool use_img_background;
4928 unsigned long bg = 0;
4930 if (img->mask)
4931 x_clear_image_1 (f, img, CLEAR_IMAGE_MASK);
4933 #ifndef HAVE_NTGUI
4934 #ifndef HAVE_NS
4935 /* Create an image and pixmap serving as mask. */
4936 if (! image_create_x_image_and_pixmap (f, img, img->width, img->height, 1,
4937 &mask_img, 1))
4938 return;
4939 #endif /* !HAVE_NS */
4940 #else
4941 /* Create the bit array serving as mask. */
4942 row_width = (img->width + 7) / 8;
4943 mask_img = xzalloc (row_width * img->height);
4944 #endif /* HAVE_NTGUI */
4946 /* Get the X image or create a memory device context for IMG. */
4947 ximg = image_get_x_image_or_dc (f, img, 0, &prev);
4949 /* Determine the background color of ximg. If HOW is `(R G B)'
4950 take that as color. Otherwise, use the image's background color. */
4951 use_img_background = 1;
4953 if (CONSP (how))
4955 int rgb[3], i;
4957 for (i = 0; i < 3 && CONSP (how) && NATNUMP (XCAR (how)); ++i)
4959 rgb[i] = XFASTINT (XCAR (how)) & 0xffff;
4960 how = XCDR (how);
4963 if (i == 3 && NILP (how))
4965 char color_name[30];
4966 sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]);
4967 bg = (
4968 #ifdef HAVE_NTGUI
4969 0x00ffffff & /* Filter out palette info. */
4970 #endif /* HAVE_NTGUI */
4971 x_alloc_image_color (f, img, build_string (color_name), 0));
4972 use_img_background = 0;
4976 if (use_img_background)
4977 bg = four_corners_best (ximg, img->corners, img->width, img->height);
4979 /* Set all bits in mask_img to 1 whose color in ximg is different
4980 from the background color bg. */
4981 #ifndef HAVE_NTGUI
4982 for (y = 0; y < img->height; ++y)
4983 for (x = 0; x < img->width; ++x)
4984 #ifndef HAVE_NS
4985 XPutPixel (mask_img, x, y, (XGetPixel (ximg, x, y) != bg
4986 ? PIX_MASK_DRAW : PIX_MASK_RETAIN));
4987 #else
4988 if (XGetPixel (ximg, x, y) == bg)
4989 ns_set_alpha (ximg, x, y, 0);
4990 #endif /* HAVE_NS */
4991 #ifndef HAVE_NS
4992 /* Fill in the background_transparent field while we have the mask handy. */
4993 image_background_transparent (img, f, mask_img);
4995 /* Put mask_img into the image. */
4996 image_put_x_image (f, img, mask_img, 1);
4997 #endif /* !HAVE_NS */
4998 #else
4999 for (y = 0; y < img->height; ++y)
5000 for (x = 0; x < img->width; ++x)
5002 COLORREF p = GetPixel (ximg, x, y);
5003 if (p != bg)
5004 mask_img[y * row_width + x / 8] |= 1 << (x % 8);
5007 /* Create the mask image. */
5008 img->mask = w32_create_pixmap_from_bitmap_data (img->width, img->height,
5009 mask_img);
5010 /* Fill in the background_transparent field while we have the mask handy. */
5011 SelectObject (ximg, img->mask);
5012 image_background_transparent (img, f, ximg);
5014 /* Was: x_destroy_x_image ((XImagePtr )mask_img); which seems bogus ++kfs */
5015 xfree (mask_img);
5016 #endif /* HAVE_NTGUI */
5018 image_unget_x_image_or_dc (img, 0, ximg, prev);
5022 /***********************************************************************
5023 PBM (mono, gray, color)
5024 ***********************************************************************/
5026 static bool pbm_image_p (Lisp_Object object);
5027 static bool pbm_load (struct frame *f, struct image *img);
5029 /* Indices of image specification fields in gs_format, below. */
5031 enum pbm_keyword_index
5033 PBM_TYPE,
5034 PBM_FILE,
5035 PBM_DATA,
5036 PBM_ASCENT,
5037 PBM_MARGIN,
5038 PBM_RELIEF,
5039 PBM_ALGORITHM,
5040 PBM_HEURISTIC_MASK,
5041 PBM_MASK,
5042 PBM_FOREGROUND,
5043 PBM_BACKGROUND,
5044 PBM_LAST
5047 /* Vector of image_keyword structures describing the format
5048 of valid user-defined image specifications. */
5050 static const struct image_keyword pbm_format[PBM_LAST] =
5052 {":type", IMAGE_SYMBOL_VALUE, 1},
5053 {":file", IMAGE_STRING_VALUE, 0},
5054 {":data", IMAGE_STRING_VALUE, 0},
5055 {":ascent", IMAGE_ASCENT_VALUE, 0},
5056 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
5057 {":relief", IMAGE_INTEGER_VALUE, 0},
5058 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5059 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5060 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5061 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
5062 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
5065 /* Structure describing the image type `pbm'. */
5067 static struct image_type pbm_type =
5069 XSYMBOL_INIT (Qpbm),
5070 pbm_image_p,
5071 pbm_load,
5072 x_clear_image,
5073 NULL,
5074 NULL
5078 /* Return true if OBJECT is a valid PBM image specification. */
5080 static bool
5081 pbm_image_p (Lisp_Object object)
5083 struct image_keyword fmt[PBM_LAST];
5085 memcpy (fmt, pbm_format, sizeof fmt);
5087 if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm))
5088 return 0;
5090 /* Must specify either :data or :file. */
5091 return fmt[PBM_DATA].count + fmt[PBM_FILE].count == 1;
5095 /* Get next char skipping comments in Netpbm header. Returns -1 at
5096 end of input. */
5098 static int
5099 pbm_next_char (unsigned char **s, unsigned char *end)
5101 int c = -1;
5103 while (*s < end && (c = *(*s)++, c == '#'))
5105 /* Skip to the next line break. */
5106 while (*s < end && (c = *(*s)++, c != '\n' && c != '\r'))
5109 c = -1;
5112 return c;
5116 /* Scan a decimal number from *S and return it. Advance *S while
5117 reading the number. END is the end of the string. Value is -1 at
5118 end of input. */
5120 static int
5121 pbm_scan_number (unsigned char **s, unsigned char *end)
5123 int c = 0, val = -1;
5125 /* Skip white-space. */
5126 while ((c = pbm_next_char (s, end)) != -1 && c_isspace (c))
5129 if (c_isdigit (c))
5131 /* Read decimal number. */
5132 val = c - '0';
5133 while ((c = pbm_next_char (s, end)) != -1 && c_isdigit (c))
5134 val = 10 * val + c - '0';
5137 return val;
5141 /* Load PBM image IMG for use on frame F. */
5143 static bool
5144 pbm_load (struct frame *f, struct image *img)
5146 bool raw_p;
5147 int x, y;
5148 int width, height, max_color_idx = 0;
5149 XImagePtr ximg;
5150 Lisp_Object file, specified_file;
5151 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
5152 unsigned char *contents = NULL;
5153 unsigned char *end, *p;
5154 ptrdiff_t size;
5156 specified_file = image_spec_value (img->spec, QCfile, NULL);
5158 if (STRINGP (specified_file))
5160 file = x_find_image_file (specified_file);
5161 if (!STRINGP (file))
5163 image_error ("Cannot find image file `%s'", specified_file, Qnil);
5164 return 0;
5167 contents = slurp_file (SSDATA (file), &size);
5168 if (contents == NULL)
5170 image_error ("Error reading `%s'", file, Qnil);
5171 return 0;
5174 p = contents;
5175 end = contents + size;
5177 else
5179 Lisp_Object data;
5180 data = image_spec_value (img->spec, QCdata, NULL);
5181 if (!STRINGP (data))
5183 image_error ("Invalid image data `%s'", data, Qnil);
5184 return 0;
5186 p = SDATA (data);
5187 end = p + SBYTES (data);
5190 /* Check magic number. */
5191 if (end - p < 2 || *p++ != 'P')
5193 image_error ("Not a PBM image: `%s'", img->spec, Qnil);
5194 error:
5195 xfree (contents);
5196 img->pixmap = NO_PIXMAP;
5197 return 0;
5200 switch (*p++)
5202 case '1':
5203 raw_p = 0, type = PBM_MONO;
5204 break;
5206 case '2':
5207 raw_p = 0, type = PBM_GRAY;
5208 break;
5210 case '3':
5211 raw_p = 0, type = PBM_COLOR;
5212 break;
5214 case '4':
5215 raw_p = 1, type = PBM_MONO;
5216 break;
5218 case '5':
5219 raw_p = 1, type = PBM_GRAY;
5220 break;
5222 case '6':
5223 raw_p = 1, type = PBM_COLOR;
5224 break;
5226 default:
5227 image_error ("Not a PBM image: `%s'", img->spec, Qnil);
5228 goto error;
5231 /* Read width, height, maximum color-component. Characters
5232 starting with `#' up to the end of a line are ignored. */
5233 width = pbm_scan_number (&p, end);
5234 height = pbm_scan_number (&p, end);
5236 if (type != PBM_MONO)
5238 max_color_idx = pbm_scan_number (&p, end);
5239 if (max_color_idx > 65535 || max_color_idx < 0)
5241 image_error ("Unsupported maximum PBM color value", Qnil, Qnil);
5242 goto error;
5246 if (!check_image_size (f, width, height))
5248 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
5249 goto error;
5252 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
5253 goto error;
5255 /* Initialize the color hash table. */
5256 init_color_table ();
5258 if (type == PBM_MONO)
5260 int c = 0, g;
5261 struct image_keyword fmt[PBM_LAST];
5262 unsigned long fg = FRAME_FOREGROUND_PIXEL (f);
5263 unsigned long bg = FRAME_BACKGROUND_PIXEL (f);
5265 /* Parse the image specification. */
5266 memcpy (fmt, pbm_format, sizeof fmt);
5267 parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm);
5269 /* Get foreground and background colors, maybe allocate colors. */
5270 if (fmt[PBM_FOREGROUND].count
5271 && STRINGP (fmt[PBM_FOREGROUND].value))
5272 fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg);
5273 if (fmt[PBM_BACKGROUND].count
5274 && STRINGP (fmt[PBM_BACKGROUND].value))
5276 bg = x_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg);
5277 img->background = bg;
5278 img->background_valid = 1;
5281 for (y = 0; y < height; ++y)
5282 for (x = 0; x < width; ++x)
5284 if (raw_p)
5286 if ((x & 7) == 0)
5288 if (p >= end)
5290 x_destroy_x_image (ximg);
5291 x_clear_image (f, img);
5292 image_error ("Invalid image size in image `%s'",
5293 img->spec, Qnil);
5294 goto error;
5296 c = *p++;
5298 g = c & 0x80;
5299 c <<= 1;
5301 else
5302 g = pbm_scan_number (&p, end);
5304 XPutPixel (ximg, x, y, g ? fg : bg);
5307 else
5309 int expected_size = height * width;
5310 if (max_color_idx > 255)
5311 expected_size *= 2;
5312 if (type == PBM_COLOR)
5313 expected_size *= 3;
5315 if (raw_p && p + expected_size > end)
5317 x_destroy_x_image (ximg);
5318 x_clear_image (f, img);
5319 image_error ("Invalid image size in image `%s'",
5320 img->spec, Qnil);
5321 goto error;
5324 for (y = 0; y < height; ++y)
5325 for (x = 0; x < width; ++x)
5327 int r, g, b;
5329 if (type == PBM_GRAY && raw_p)
5331 r = g = b = *p++;
5332 if (max_color_idx > 255)
5333 r = g = b = r * 256 + *p++;
5335 else if (type == PBM_GRAY)
5336 r = g = b = pbm_scan_number (&p, end);
5337 else if (raw_p)
5339 r = *p++;
5340 if (max_color_idx > 255)
5341 r = r * 256 + *p++;
5342 g = *p++;
5343 if (max_color_idx > 255)
5344 g = g * 256 + *p++;
5345 b = *p++;
5346 if (max_color_idx > 255)
5347 b = b * 256 + *p++;
5349 else
5351 r = pbm_scan_number (&p, end);
5352 g = pbm_scan_number (&p, end);
5353 b = pbm_scan_number (&p, end);
5356 if (r < 0 || g < 0 || b < 0)
5358 x_destroy_x_image (ximg);
5359 image_error ("Invalid pixel value in image `%s'",
5360 img->spec, Qnil);
5361 goto error;
5364 /* RGB values are now in the range 0..max_color_idx.
5365 Scale this to the range 0..0xffff supported by X. */
5366 r = (double) r * 65535 / max_color_idx;
5367 g = (double) g * 65535 / max_color_idx;
5368 b = (double) b * 65535 / max_color_idx;
5369 XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
5373 #ifdef COLOR_TABLE_SUPPORT
5374 /* Store in IMG->colors the colors allocated for the image, and
5375 free the color table. */
5376 img->colors = colors_in_color_table (&img->ncolors);
5377 free_color_table ();
5378 #endif /* COLOR_TABLE_SUPPORT */
5380 img->width = width;
5381 img->height = height;
5383 /* Maybe fill in the background field while we have ximg handy. */
5385 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
5386 /* Casting avoids a GCC warning. */
5387 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
5389 /* Put ximg into the image. */
5390 image_put_x_image (f, img, ximg, 0);
5392 /* X and W32 versions did it here, MAC version above. ++kfs
5393 img->width = width;
5394 img->height = height; */
5396 xfree (contents);
5397 return 1;
5401 /***********************************************************************
5403 ***********************************************************************/
5405 #if defined (HAVE_PNG) || defined (HAVE_NS)
5407 /* Function prototypes. */
5409 static bool png_image_p (Lisp_Object object);
5410 static bool png_load (struct frame *f, struct image *img);
5412 /* Indices of image specification fields in png_format, below. */
5414 enum png_keyword_index
5416 PNG_TYPE,
5417 PNG_DATA,
5418 PNG_FILE,
5419 PNG_ASCENT,
5420 PNG_MARGIN,
5421 PNG_RELIEF,
5422 PNG_ALGORITHM,
5423 PNG_HEURISTIC_MASK,
5424 PNG_MASK,
5425 PNG_BACKGROUND,
5426 PNG_LAST
5429 /* Vector of image_keyword structures describing the format
5430 of valid user-defined image specifications. */
5432 static const struct image_keyword png_format[PNG_LAST] =
5434 {":type", IMAGE_SYMBOL_VALUE, 1},
5435 {":data", IMAGE_STRING_VALUE, 0},
5436 {":file", IMAGE_STRING_VALUE, 0},
5437 {":ascent", IMAGE_ASCENT_VALUE, 0},
5438 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
5439 {":relief", IMAGE_INTEGER_VALUE, 0},
5440 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5441 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5442 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5443 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
5446 #if defined HAVE_NTGUI && defined WINDOWSNT
5447 static bool init_png_functions (void);
5448 #else
5449 #define init_png_functions NULL
5450 #endif
5452 /* Structure describing the image type `png'. */
5454 static struct image_type png_type =
5456 XSYMBOL_INIT (Qpng),
5457 png_image_p,
5458 png_load,
5459 x_clear_image,
5460 init_png_functions,
5461 NULL
5464 /* Return true if OBJECT is a valid PNG image specification. */
5466 static bool
5467 png_image_p (Lisp_Object object)
5469 struct image_keyword fmt[PNG_LAST];
5470 memcpy (fmt, png_format, sizeof fmt);
5472 if (!parse_image_spec (object, fmt, PNG_LAST, Qpng))
5473 return 0;
5475 /* Must specify either the :data or :file keyword. */
5476 return fmt[PNG_FILE].count + fmt[PNG_DATA].count == 1;
5479 #endif /* HAVE_PNG || HAVE_NS */
5482 #if defined HAVE_PNG && !defined HAVE_NS
5484 # ifdef WINDOWSNT
5485 /* PNG library details. */
5487 DEF_DLL_FN (png_voidp, png_get_io_ptr, (png_structp));
5488 DEF_DLL_FN (int, png_sig_cmp, (png_bytep, png_size_t, png_size_t));
5489 DEF_DLL_FN (png_structp, png_create_read_struct,
5490 (png_const_charp, png_voidp, png_error_ptr, png_error_ptr));
5491 DEF_DLL_FN (png_infop, png_create_info_struct, (png_structp));
5492 DEF_DLL_FN (void, png_destroy_read_struct,
5493 (png_structpp, png_infopp, png_infopp));
5494 DEF_DLL_FN (void, png_set_read_fn, (png_structp, png_voidp, png_rw_ptr));
5495 DEF_DLL_FN (void, png_set_sig_bytes, (png_structp, int));
5496 DEF_DLL_FN (void, png_read_info, (png_structp, png_infop));
5497 DEF_DLL_FN (png_uint_32, png_get_IHDR,
5498 (png_structp, png_infop, png_uint_32 *, png_uint_32 *,
5499 int *, int *, int *, int *, int *));
5500 DEF_DLL_FN (png_uint_32, png_get_valid, (png_structp, png_infop, png_uint_32));
5501 DEF_DLL_FN (void, png_set_strip_16, (png_structp));
5502 DEF_DLL_FN (void, png_set_expand, (png_structp));
5503 DEF_DLL_FN (void, png_set_gray_to_rgb, (png_structp));
5504 DEF_DLL_FN (void, png_set_background,
5505 (png_structp, png_color_16p, int, int, double));
5506 DEF_DLL_FN (png_uint_32, png_get_bKGD,
5507 (png_structp, png_infop, png_color_16p *));
5508 DEF_DLL_FN (void, png_read_update_info, (png_structp, png_infop));
5509 DEF_DLL_FN (png_byte, png_get_channels, (png_structp, png_infop));
5510 DEF_DLL_FN (png_size_t, png_get_rowbytes, (png_structp, png_infop));
5511 DEF_DLL_FN (void, png_read_image, (png_structp, png_bytepp));
5512 DEF_DLL_FN (void, png_read_end, (png_structp, png_infop));
5513 DEF_DLL_FN (void, png_error, (png_structp, png_const_charp));
5515 # if (PNG_LIBPNG_VER >= 10500)
5516 DEF_DLL_FN (void, png_longjmp, (png_structp, int)) PNG_NORETURN;
5517 DEF_DLL_FN (jmp_buf *, png_set_longjmp_fn,
5518 (png_structp, png_longjmp_ptr, size_t));
5519 # endif /* libpng version >= 1.5 */
5521 static bool
5522 init_png_functions (void)
5524 HMODULE library;
5526 if (!(library = w32_delayed_load (Qpng)))
5527 return 0;
5529 LOAD_DLL_FN (library, png_get_io_ptr);
5530 LOAD_DLL_FN (library, png_sig_cmp);
5531 LOAD_DLL_FN (library, png_create_read_struct);
5532 LOAD_DLL_FN (library, png_create_info_struct);
5533 LOAD_DLL_FN (library, png_destroy_read_struct);
5534 LOAD_DLL_FN (library, png_set_read_fn);
5535 LOAD_DLL_FN (library, png_set_sig_bytes);
5536 LOAD_DLL_FN (library, png_read_info);
5537 LOAD_DLL_FN (library, png_get_IHDR);
5538 LOAD_DLL_FN (library, png_get_valid);
5539 LOAD_DLL_FN (library, png_set_strip_16);
5540 LOAD_DLL_FN (library, png_set_expand);
5541 LOAD_DLL_FN (library, png_set_gray_to_rgb);
5542 LOAD_DLL_FN (library, png_set_background);
5543 LOAD_DLL_FN (library, png_get_bKGD);
5544 LOAD_DLL_FN (library, png_read_update_info);
5545 LOAD_DLL_FN (library, png_get_channels);
5546 LOAD_DLL_FN (library, png_get_rowbytes);
5547 LOAD_DLL_FN (library, png_read_image);
5548 LOAD_DLL_FN (library, png_read_end);
5549 LOAD_DLL_FN (library, png_error);
5551 # if (PNG_LIBPNG_VER >= 10500)
5552 LOAD_DLL_FN (library, png_longjmp);
5553 LOAD_DLL_FN (library, png_set_longjmp_fn);
5554 # endif /* libpng version >= 1.5 */
5556 return 1;
5559 # undef png_create_info_struct
5560 # undef png_create_read_struct
5561 # undef png_destroy_read_struct
5562 # undef png_error
5563 # undef png_get_bKGD
5564 # undef png_get_channels
5565 # undef png_get_IHDR
5566 # undef png_get_io_ptr
5567 # undef png_get_rowbytes
5568 # undef png_get_valid
5569 # undef png_longjmp
5570 # undef png_read_end
5571 # undef png_read_image
5572 # undef png_read_info
5573 # undef png_read_update_info
5574 # undef png_set_background
5575 # undef png_set_expand
5576 # undef png_set_gray_to_rgb
5577 # undef png_set_longjmp_fn
5578 # undef png_set_read_fn
5579 # undef png_set_sig_bytes
5580 # undef png_set_strip_16
5581 # undef png_sig_cmp
5583 # define png_create_info_struct fn_png_create_info_struct
5584 # define png_create_read_struct fn_png_create_read_struct
5585 # define png_destroy_read_struct fn_png_destroy_read_struct
5586 # define png_error fn_png_error
5587 # define png_get_bKGD fn_png_get_bKGD
5588 # define png_get_channels fn_png_get_channels
5589 # define png_get_IHDR fn_png_get_IHDR
5590 # define png_get_io_ptr fn_png_get_io_ptr
5591 # define png_get_rowbytes fn_png_get_rowbytes
5592 # define png_get_valid fn_png_get_valid
5593 # define png_longjmp fn_png_longjmp
5594 # define png_read_end fn_png_read_end
5595 # define png_read_image fn_png_read_image
5596 # define png_read_info fn_png_read_info
5597 # define png_read_update_info fn_png_read_update_info
5598 # define png_set_background fn_png_set_background
5599 # define png_set_expand fn_png_set_expand
5600 # define png_set_gray_to_rgb fn_png_set_gray_to_rgb
5601 # define png_set_longjmp_fn fn_png_set_longjmp_fn
5602 # define png_set_read_fn fn_png_set_read_fn
5603 # define png_set_sig_bytes fn_png_set_sig_bytes
5604 # define png_set_strip_16 fn_png_set_strip_16
5605 # define png_sig_cmp fn_png_sig_cmp
5607 # endif /* WINDOWSNT */
5609 /* Fast implementations of setjmp and longjmp. Although setjmp and longjmp
5610 will do, POSIX _setjmp and _longjmp (if available) are often faster.
5611 Do not use sys_setjmp, as PNG supports only jmp_buf.
5612 It's OK if the longjmp substitute restores the signal mask. */
5613 # ifdef HAVE__SETJMP
5614 # define FAST_SETJMP(j) _setjmp (j)
5615 # define FAST_LONGJMP _longjmp
5616 # else
5617 # define FAST_SETJMP(j) setjmp (j)
5618 # define FAST_LONGJMP longjmp
5619 # endif
5621 # if PNG_LIBPNG_VER < 10500
5622 # define PNG_LONGJMP(ptr) FAST_LONGJMP ((ptr)->jmpbuf, 1)
5623 # define PNG_JMPBUF(ptr) ((ptr)->jmpbuf)
5624 # else
5625 /* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908) */
5626 # define PNG_LONGJMP(ptr) png_longjmp (ptr, 1)
5627 # define PNG_JMPBUF(ptr) \
5628 (*png_set_longjmp_fn (ptr, FAST_LONGJMP, sizeof (jmp_buf)))
5629 # endif
5631 /* Error and warning handlers installed when the PNG library
5632 is initialized. */
5634 static _Noreturn void
5635 my_png_error (png_struct *png_ptr, const char *msg)
5637 eassert (png_ptr != NULL);
5638 /* Avoid compiler warning about deprecated direct access to
5639 png_ptr's fields in libpng versions 1.4.x. */
5640 image_error ("PNG error: %s", build_string (msg), Qnil);
5641 PNG_LONGJMP (png_ptr);
5645 static void
5646 my_png_warning (png_struct *png_ptr, const char *msg)
5648 eassert (png_ptr != NULL);
5649 image_error ("PNG warning: %s", build_string (msg), Qnil);
5652 /* Memory source for PNG decoding. */
5654 struct png_memory_storage
5656 unsigned char *bytes; /* The data */
5657 ptrdiff_t len; /* How big is it? */
5658 ptrdiff_t index; /* Where are we? */
5662 /* Function set as reader function when reading PNG image from memory.
5663 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5664 bytes from the input to DATA. */
5666 static void
5667 png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length)
5669 struct png_memory_storage *tbr = png_get_io_ptr (png_ptr);
5671 if (length > tbr->len - tbr->index)
5672 png_error (png_ptr, "Read error");
5674 memcpy (data, tbr->bytes + tbr->index, length);
5675 tbr->index = tbr->index + length;
5679 /* Function set as reader function when reading PNG image from a file.
5680 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5681 bytes from the input to DATA. */
5683 static void
5684 png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length)
5686 FILE *fp = png_get_io_ptr (png_ptr);
5688 if (fread (data, 1, length, fp) < length)
5689 png_error (png_ptr, "Read error");
5693 /* Load PNG image IMG for use on frame F. Value is true if
5694 successful. */
5696 struct png_load_context
5698 /* These are members so that longjmp doesn't munge local variables. */
5699 png_struct *png_ptr;
5700 png_info *info_ptr;
5701 png_info *end_info;
5702 FILE *fp;
5703 png_byte *pixels;
5704 png_byte **rows;
5707 static bool
5708 png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5710 Lisp_Object file, specified_file;
5711 Lisp_Object specified_data;
5712 int x, y;
5713 ptrdiff_t i;
5714 XImagePtr ximg, mask_img = NULL;
5715 png_struct *png_ptr;
5716 png_info *info_ptr = NULL, *end_info = NULL;
5717 FILE *fp = NULL;
5718 png_byte sig[8];
5719 png_byte *pixels = NULL;
5720 png_byte **rows = NULL;
5721 png_uint_32 width, height;
5722 int bit_depth, color_type, interlace_type;
5723 png_byte channels;
5724 png_uint_32 row_bytes;
5725 bool transparent_p;
5726 struct png_memory_storage tbr; /* Data to be read */
5728 /* Find out what file to load. */
5729 specified_file = image_spec_value (img->spec, QCfile, NULL);
5730 specified_data = image_spec_value (img->spec, QCdata, NULL);
5732 if (NILP (specified_data))
5734 file = x_find_image_file (specified_file);
5735 if (!STRINGP (file))
5737 image_error ("Cannot find image file `%s'", specified_file, Qnil);
5738 return 0;
5741 /* Open the image file. */
5742 fp = emacs_fopen (SSDATA (file), "rb");
5743 if (!fp)
5745 image_error ("Cannot open image file `%s'", file, Qnil);
5746 return 0;
5749 /* Check PNG signature. */
5750 if (fread (sig, 1, sizeof sig, fp) != sizeof sig
5751 || png_sig_cmp (sig, 0, sizeof sig))
5753 fclose (fp);
5754 image_error ("Not a PNG file: `%s'", file, Qnil);
5755 return 0;
5758 else
5760 if (!STRINGP (specified_data))
5762 image_error ("Invalid image data `%s'", specified_data, Qnil);
5763 return 0;
5766 /* Read from memory. */
5767 tbr.bytes = SDATA (specified_data);
5768 tbr.len = SBYTES (specified_data);
5769 tbr.index = 0;
5771 /* Check PNG signature. */
5772 if (tbr.len < sizeof sig
5773 || png_sig_cmp (tbr.bytes, 0, sizeof sig))
5775 image_error ("Not a PNG image: `%s'", img->spec, Qnil);
5776 return 0;
5779 /* Need to skip past the signature. */
5780 tbr.bytes += sizeof (sig);
5783 /* Initialize read and info structs for PNG lib. */
5784 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,
5785 NULL, my_png_error,
5786 my_png_warning);
5787 if (png_ptr)
5789 info_ptr = png_create_info_struct (png_ptr);
5790 end_info = png_create_info_struct (png_ptr);
5793 c->png_ptr = png_ptr;
5794 c->info_ptr = info_ptr;
5795 c->end_info = end_info;
5796 c->fp = fp;
5797 c->pixels = pixels;
5798 c->rows = rows;
5800 if (! (info_ptr && end_info))
5802 png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
5803 png_ptr = 0;
5805 if (! png_ptr)
5807 if (fp) fclose (fp);
5808 return 0;
5811 /* Set error jump-back. We come back here when the PNG library
5812 detects an error. */
5813 if (FAST_SETJMP (PNG_JMPBUF (png_ptr)))
5815 error:
5816 if (c->png_ptr)
5817 png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
5818 xfree (c->pixels);
5819 xfree (c->rows);
5820 if (c->fp)
5821 fclose (c->fp);
5822 return 0;
5825 /* Silence a bogus diagnostic; see GCC bug 54561. */
5826 IF_LINT (fp = c->fp);
5828 /* Read image info. */
5829 if (!NILP (specified_data))
5830 png_set_read_fn (png_ptr, &tbr, png_read_from_memory);
5831 else
5832 png_set_read_fn (png_ptr, fp, png_read_from_file);
5834 png_set_sig_bytes (png_ptr, sizeof sig);
5835 png_read_info (png_ptr, info_ptr);
5836 png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
5837 &interlace_type, NULL, NULL);
5839 if (! (width <= INT_MAX && height <= INT_MAX
5840 && check_image_size (f, width, height)))
5842 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
5843 goto error;
5846 /* Create the X image and pixmap now, so that the work below can be
5847 omitted if the image is too large for X. */
5848 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
5849 goto error;
5851 /* If image contains simply transparency data, we prefer to
5852 construct a clipping mask. */
5853 if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
5854 transparent_p = 1;
5855 else
5856 transparent_p = 0;
5858 /* This function is easier to write if we only have to handle
5859 one data format: RGB or RGBA with 8 bits per channel. Let's
5860 transform other formats into that format. */
5862 /* Strip more than 8 bits per channel. */
5863 if (bit_depth == 16)
5864 png_set_strip_16 (png_ptr);
5866 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
5867 if available. */
5868 png_set_expand (png_ptr);
5870 /* Convert grayscale images to RGB. */
5871 if (color_type == PNG_COLOR_TYPE_GRAY
5872 || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
5873 png_set_gray_to_rgb (png_ptr);
5875 /* Handle alpha channel by combining the image with a background
5876 color. Do this only if a real alpha channel is supplied. For
5877 simple transparency, we prefer a clipping mask. */
5878 if (!transparent_p)
5880 /* png_color_16 *image_bg; */
5881 Lisp_Object specified_bg
5882 = image_spec_value (img->spec, QCbackground, NULL);
5883 XColor color;
5885 /* If the user specified a color, try to use it; if not, use the
5886 current frame background, ignoring any default background
5887 color set by the image. */
5888 if (STRINGP (specified_bg)
5889 ? x_defined_color (f, SSDATA (specified_bg), &color, false)
5890 : (x_query_frame_background_color (f, &color), true))
5891 /* The user specified `:background', use that. */
5893 int shift = bit_depth == 16 ? 0 : 8;
5894 png_color_16 bg = { 0 };
5895 bg.red = color.red >> shift;
5896 bg.green = color.green >> shift;
5897 bg.blue = color.blue >> shift;
5899 png_set_background (png_ptr, &bg,
5900 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
5904 /* Update info structure. */
5905 png_read_update_info (png_ptr, info_ptr);
5907 /* Get number of channels. Valid values are 1 for grayscale images
5908 and images with a palette, 2 for grayscale images with transparency
5909 information (alpha channel), 3 for RGB images, and 4 for RGB
5910 images with alpha channel, i.e. RGBA. If conversions above were
5911 sufficient we should only have 3 or 4 channels here. */
5912 channels = png_get_channels (png_ptr, info_ptr);
5913 eassert (channels == 3 || channels == 4);
5915 /* Number of bytes needed for one row of the image. */
5916 row_bytes = png_get_rowbytes (png_ptr, info_ptr);
5918 /* Allocate memory for the image. */
5919 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height
5920 || min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height < row_bytes)
5921 memory_full (SIZE_MAX);
5922 c->pixels = pixels = xmalloc (sizeof *pixels * row_bytes * height);
5923 c->rows = rows = xmalloc (height * sizeof *rows);
5924 for (i = 0; i < height; ++i)
5925 rows[i] = pixels + i * row_bytes;
5927 /* Read the entire image. */
5928 png_read_image (png_ptr, rows);
5929 png_read_end (png_ptr, info_ptr);
5930 if (fp)
5932 fclose (fp);
5933 c->fp = NULL;
5936 /* Create an image and pixmap serving as mask if the PNG image
5937 contains an alpha channel. */
5938 if (channels == 4
5939 && !transparent_p
5940 && !image_create_x_image_and_pixmap (f, img, width, height, 1,
5941 &mask_img, 1))
5943 x_destroy_x_image (ximg);
5944 x_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP);
5945 goto error;
5948 /* Fill the X image and mask from PNG data. */
5949 init_color_table ();
5951 for (y = 0; y < height; ++y)
5953 png_byte *p = rows[y];
5955 for (x = 0; x < width; ++x)
5957 int r, g, b;
5959 r = *p++ << 8;
5960 g = *p++ << 8;
5961 b = *p++ << 8;
5962 XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
5963 /* An alpha channel, aka mask channel, associates variable
5964 transparency with an image. Where other image formats
5965 support binary transparency---fully transparent or fully
5966 opaque---PNG allows up to 254 levels of partial transparency.
5967 The PNG library implements partial transparency by combining
5968 the image with a specified background color.
5970 I'm not sure how to handle this here nicely: because the
5971 background on which the image is displayed may change, for
5972 real alpha channel support, it would be necessary to create
5973 a new image for each possible background.
5975 What I'm doing now is that a mask is created if we have
5976 boolean transparency information. Otherwise I'm using
5977 the frame's background color to combine the image with. */
5979 if (channels == 4)
5981 if (mask_img)
5982 XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN);
5983 ++p;
5988 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
5989 /* Set IMG's background color from the PNG image, unless the user
5990 overrode it. */
5992 png_color_16 *bg;
5993 if (png_get_bKGD (png_ptr, info_ptr, &bg))
5995 img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue);
5996 img->background_valid = 1;
6000 # ifdef COLOR_TABLE_SUPPORT
6001 /* Remember colors allocated for this image. */
6002 img->colors = colors_in_color_table (&img->ncolors);
6003 free_color_table ();
6004 # endif /* COLOR_TABLE_SUPPORT */
6006 /* Clean up. */
6007 png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
6008 xfree (rows);
6009 xfree (pixels);
6011 img->width = width;
6012 img->height = height;
6014 /* Maybe fill in the background field while we have ximg handy.
6015 Casting avoids a GCC warning. */
6016 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
6018 /* Put ximg into the image. */
6019 image_put_x_image (f, img, ximg, 0);
6021 /* Same for the mask. */
6022 if (mask_img)
6024 /* Fill in the background_transparent field while we have the
6025 mask handy. Casting avoids a GCC warning. */
6026 image_background_transparent (img, f, (XImagePtr_or_DC)mask_img);
6028 image_put_x_image (f, img, mask_img, 1);
6031 return 1;
6034 static bool
6035 png_load (struct frame *f, struct image *img)
6037 struct png_load_context c;
6038 return png_load_body (f, img, &c);
6041 #elif defined HAVE_NS
6043 static bool
6044 png_load (struct frame *f, struct image *img)
6046 return ns_load_image (f, img,
6047 image_spec_value (img->spec, QCfile, NULL),
6048 image_spec_value (img->spec, QCdata, NULL));
6051 #endif /* HAVE_NS */
6055 /***********************************************************************
6056 JPEG
6057 ***********************************************************************/
6059 #if defined (HAVE_JPEG) || defined (HAVE_NS)
6061 static bool jpeg_image_p (Lisp_Object object);
6062 static bool jpeg_load (struct frame *f, struct image *img);
6064 /* Indices of image specification fields in gs_format, below. */
6066 enum jpeg_keyword_index
6068 JPEG_TYPE,
6069 JPEG_DATA,
6070 JPEG_FILE,
6071 JPEG_ASCENT,
6072 JPEG_MARGIN,
6073 JPEG_RELIEF,
6074 JPEG_ALGORITHM,
6075 JPEG_HEURISTIC_MASK,
6076 JPEG_MASK,
6077 JPEG_BACKGROUND,
6078 JPEG_LAST
6081 /* Vector of image_keyword structures describing the format
6082 of valid user-defined image specifications. */
6084 static const struct image_keyword jpeg_format[JPEG_LAST] =
6086 {":type", IMAGE_SYMBOL_VALUE, 1},
6087 {":data", IMAGE_STRING_VALUE, 0},
6088 {":file", IMAGE_STRING_VALUE, 0},
6089 {":ascent", IMAGE_ASCENT_VALUE, 0},
6090 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
6091 {":relief", IMAGE_INTEGER_VALUE, 0},
6092 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6093 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6094 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6095 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
6098 #if defined HAVE_NTGUI && defined WINDOWSNT
6099 static bool init_jpeg_functions (void);
6100 #else
6101 #define init_jpeg_functions NULL
6102 #endif
6104 /* Structure describing the image type `jpeg'. */
6106 static struct image_type jpeg_type =
6108 XSYMBOL_INIT (Qjpeg),
6109 jpeg_image_p,
6110 jpeg_load,
6111 x_clear_image,
6112 init_jpeg_functions,
6113 NULL
6116 /* Return true if OBJECT is a valid JPEG image specification. */
6118 static bool
6119 jpeg_image_p (Lisp_Object object)
6121 struct image_keyword fmt[JPEG_LAST];
6123 memcpy (fmt, jpeg_format, sizeof fmt);
6125 if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg))
6126 return 0;
6128 /* Must specify either the :data or :file keyword. */
6129 return fmt[JPEG_FILE].count + fmt[JPEG_DATA].count == 1;
6132 #endif /* HAVE_JPEG || HAVE_NS */
6134 #ifdef HAVE_JPEG
6136 /* Work around a warning about HAVE_STDLIB_H being redefined in
6137 jconfig.h. */
6138 # ifdef HAVE_STDLIB_H
6139 # undef HAVE_STDLIB_H
6140 # endif
6142 # if defined (HAVE_NTGUI) && !defined (__WIN32__)
6143 /* In older releases of the jpeg library, jpeglib.h will define boolean
6144 differently depending on __WIN32__, so make sure it is defined. */
6145 # define __WIN32__ 1
6146 # endif
6148 /* rpcndr.h (via windows.h) and jpeglib.h both define boolean types.
6149 Some versions of jpeglib try to detect whether rpcndr.h is loaded,
6150 using the Windows boolean type instead of the jpeglib boolean type
6151 if so. Cygwin jpeglib, however, doesn't try to detect whether its
6152 headers are included along with windows.h, so under Cygwin, jpeglib
6153 attempts to define a conflicting boolean type. Worse, forcing
6154 Cygwin jpeglib headers to use the Windows boolean type doesn't work
6155 because it created an ABI incompatibility between the
6156 already-compiled jpeg library and the header interface definition.
6158 The best we can do is to define jpeglib's boolean type to a
6159 different name. This name, jpeg_boolean, remains in effect through
6160 the rest of image.c.
6162 # if defined CYGWIN && defined HAVE_NTGUI
6163 # define boolean jpeg_boolean
6164 # endif
6165 # include <jpeglib.h>
6166 # include <jerror.h>
6168 # ifdef WINDOWSNT
6170 /* JPEG library details. */
6171 DEF_DLL_FN (void, jpeg_CreateDecompress, (j_decompress_ptr, int, size_t));
6172 DEF_DLL_FN (boolean, jpeg_start_decompress, (j_decompress_ptr));
6173 DEF_DLL_FN (boolean, jpeg_finish_decompress, (j_decompress_ptr));
6174 DEF_DLL_FN (void, jpeg_destroy_decompress, (j_decompress_ptr));
6175 DEF_DLL_FN (int, jpeg_read_header, (j_decompress_ptr, boolean));
6176 DEF_DLL_FN (JDIMENSION, jpeg_read_scanlines,
6177 (j_decompress_ptr, JSAMPARRAY, JDIMENSION));
6178 DEF_DLL_FN (struct jpeg_error_mgr *, jpeg_std_error,
6179 (struct jpeg_error_mgr *));
6180 DEF_DLL_FN (boolean, jpeg_resync_to_restart, (j_decompress_ptr, int));
6182 static bool
6183 init_jpeg_functions (void)
6185 HMODULE library;
6187 if (!(library = w32_delayed_load (Qjpeg)))
6188 return 0;
6190 LOAD_DLL_FN (library, jpeg_finish_decompress);
6191 LOAD_DLL_FN (library, jpeg_read_scanlines);
6192 LOAD_DLL_FN (library, jpeg_start_decompress);
6193 LOAD_DLL_FN (library, jpeg_read_header);
6194 LOAD_DLL_FN (library, jpeg_CreateDecompress);
6195 LOAD_DLL_FN (library, jpeg_destroy_decompress);
6196 LOAD_DLL_FN (library, jpeg_std_error);
6197 LOAD_DLL_FN (library, jpeg_resync_to_restart);
6198 return 1;
6201 # undef jpeg_CreateDecompress
6202 # undef jpeg_destroy_decompress
6203 # undef jpeg_finish_decompress
6204 # undef jpeg_read_header
6205 # undef jpeg_read_scanlines
6206 # undef jpeg_resync_to_restart
6207 # undef jpeg_start_decompress
6208 # undef jpeg_std_error
6210 # define jpeg_CreateDecompress fn_jpeg_CreateDecompress
6211 # define jpeg_destroy_decompress fn_jpeg_destroy_decompress
6212 # define jpeg_finish_decompress fn_jpeg_finish_decompress
6213 # define jpeg_read_header fn_jpeg_read_header
6214 # define jpeg_read_scanlines fn_jpeg_read_scanlines
6215 # define jpeg_resync_to_restart fn_jpeg_resync_to_restart
6216 # define jpeg_start_decompress fn_jpeg_start_decompress
6217 # define jpeg_std_error fn_jpeg_std_error
6219 /* Wrapper since we can't directly assign the function pointer
6220 to another function pointer that was declared more completely easily. */
6221 static boolean
6222 jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo, int desired)
6224 return jpeg_resync_to_restart (cinfo, desired);
6226 # undef jpeg_resync_to_restart
6227 # define jpeg_resync_to_restart jpeg_resync_to_restart_wrapper
6229 # endif /* WINDOWSNT */
6231 struct my_jpeg_error_mgr
6233 struct jpeg_error_mgr pub;
6234 sys_jmp_buf setjmp_buffer;
6236 /* The remaining members are so that longjmp doesn't munge local
6237 variables. */
6238 struct jpeg_decompress_struct cinfo;
6239 enum
6241 MY_JPEG_ERROR_EXIT,
6242 MY_JPEG_INVALID_IMAGE_SIZE,
6243 MY_JPEG_CANNOT_CREATE_X
6244 } failure_code;
6248 static _Noreturn void
6249 my_error_exit (j_common_ptr cinfo)
6251 struct my_jpeg_error_mgr *mgr = (struct my_jpeg_error_mgr *) cinfo->err;
6252 mgr->failure_code = MY_JPEG_ERROR_EXIT;
6253 sys_longjmp (mgr->setjmp_buffer, 1);
6257 /* Init source method for JPEG data source manager. Called by
6258 jpeg_read_header() before any data is actually read. See
6259 libjpeg.doc from the JPEG lib distribution. */
6261 static void
6262 our_common_init_source (j_decompress_ptr cinfo)
6267 /* Method to terminate data source. Called by
6268 jpeg_finish_decompress() after all data has been processed. */
6270 static void
6271 our_common_term_source (j_decompress_ptr cinfo)
6276 /* Fill input buffer method for JPEG data source manager. Called
6277 whenever more data is needed. We read the whole image in one step,
6278 so this only adds a fake end of input marker at the end. */
6280 static JOCTET our_memory_buffer[2];
6282 static boolean
6283 our_memory_fill_input_buffer (j_decompress_ptr cinfo)
6285 /* Insert a fake EOI marker. */
6286 struct jpeg_source_mgr *src = cinfo->src;
6288 our_memory_buffer[0] = (JOCTET) 0xFF;
6289 our_memory_buffer[1] = (JOCTET) JPEG_EOI;
6291 src->next_input_byte = our_memory_buffer;
6292 src->bytes_in_buffer = 2;
6293 return 1;
6297 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6298 is the JPEG data source manager. */
6300 static void
6301 our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes)
6303 struct jpeg_source_mgr *src = cinfo->src;
6305 if (src)
6307 if (num_bytes > src->bytes_in_buffer)
6308 ERREXIT (cinfo, JERR_INPUT_EOF);
6310 src->bytes_in_buffer -= num_bytes;
6311 src->next_input_byte += num_bytes;
6316 /* Set up the JPEG lib for reading an image from DATA which contains
6317 LEN bytes. CINFO is the decompression info structure created for
6318 reading the image. */
6320 static void
6321 jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, ptrdiff_t len)
6323 struct jpeg_source_mgr *src = cinfo->src;
6325 if (! src)
6327 /* First time for this JPEG object? */
6328 src = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
6329 JPOOL_PERMANENT, sizeof *src);
6330 cinfo->src = src;
6331 src->next_input_byte = data;
6334 src->init_source = our_common_init_source;
6335 src->fill_input_buffer = our_memory_fill_input_buffer;
6336 src->skip_input_data = our_memory_skip_input_data;
6337 src->resync_to_restart = jpeg_resync_to_restart; /* Use default method. */
6338 src->term_source = our_common_term_source;
6339 src->bytes_in_buffer = len;
6340 src->next_input_byte = data;
6344 struct jpeg_stdio_mgr
6346 struct jpeg_source_mgr mgr;
6347 boolean finished;
6348 FILE *file;
6349 JOCTET *buffer;
6353 /* Size of buffer to read JPEG from file.
6354 Not too big, as we want to use alloc_small. */
6355 #define JPEG_STDIO_BUFFER_SIZE 8192
6358 /* Fill input buffer method for JPEG data source manager. Called
6359 whenever more data is needed. The data is read from a FILE *. */
6361 static boolean
6362 our_stdio_fill_input_buffer (j_decompress_ptr cinfo)
6364 struct jpeg_stdio_mgr *src;
6366 src = (struct jpeg_stdio_mgr *) cinfo->src;
6367 if (!src->finished)
6369 ptrdiff_t bytes;
6371 bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file);
6372 if (bytes > 0)
6373 src->mgr.bytes_in_buffer = bytes;
6374 else
6376 WARNMS (cinfo, JWRN_JPEG_EOF);
6377 src->finished = 1;
6378 src->buffer[0] = (JOCTET) 0xFF;
6379 src->buffer[1] = (JOCTET) JPEG_EOI;
6380 src->mgr.bytes_in_buffer = 2;
6382 src->mgr.next_input_byte = src->buffer;
6385 return 1;
6389 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6390 is the JPEG data source manager. */
6392 static void
6393 our_stdio_skip_input_data (j_decompress_ptr cinfo, long int num_bytes)
6395 struct jpeg_stdio_mgr *src;
6396 src = (struct jpeg_stdio_mgr *) cinfo->src;
6398 while (num_bytes > 0 && !src->finished)
6400 if (num_bytes <= src->mgr.bytes_in_buffer)
6402 src->mgr.bytes_in_buffer -= num_bytes;
6403 src->mgr.next_input_byte += num_bytes;
6404 break;
6406 else
6408 num_bytes -= src->mgr.bytes_in_buffer;
6409 src->mgr.bytes_in_buffer = 0;
6410 src->mgr.next_input_byte = NULL;
6412 our_stdio_fill_input_buffer (cinfo);
6418 /* Set up the JPEG lib for reading an image from a FILE *.
6419 CINFO is the decompression info structure created for
6420 reading the image. */
6422 static void
6423 jpeg_file_src (j_decompress_ptr cinfo, FILE *fp)
6425 struct jpeg_stdio_mgr *src = (struct jpeg_stdio_mgr *) cinfo->src;
6427 if (! src)
6429 /* First time for this JPEG object? */
6430 src = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
6431 JPOOL_PERMANENT, sizeof *src);
6432 cinfo->src = (struct jpeg_source_mgr *) src;
6433 src->buffer = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
6434 JPOOL_PERMANENT,
6435 JPEG_STDIO_BUFFER_SIZE);
6438 src->file = fp;
6439 src->finished = 0;
6440 src->mgr.init_source = our_common_init_source;
6441 src->mgr.fill_input_buffer = our_stdio_fill_input_buffer;
6442 src->mgr.skip_input_data = our_stdio_skip_input_data;
6443 src->mgr.resync_to_restart = jpeg_resync_to_restart; /* Use default. */
6444 src->mgr.term_source = our_common_term_source;
6445 src->mgr.bytes_in_buffer = 0;
6446 src->mgr.next_input_byte = NULL;
6449 /* Load image IMG for use on frame F. Patterned after example.c
6450 from the JPEG lib. */
6452 static bool
6453 jpeg_load_body (struct frame *f, struct image *img,
6454 struct my_jpeg_error_mgr *mgr)
6456 Lisp_Object file, specified_file;
6457 Lisp_Object specified_data;
6458 /* The 'volatile' silences a bogus diagnostic; see GCC bug 54561. */
6459 FILE * IF_LINT (volatile) fp = NULL;
6460 JSAMPARRAY buffer;
6461 int row_stride, x, y;
6462 XImagePtr ximg = NULL;
6463 unsigned long *colors;
6464 int width, height;
6466 /* Open the JPEG file. */
6467 specified_file = image_spec_value (img->spec, QCfile, NULL);
6468 specified_data = image_spec_value (img->spec, QCdata, NULL);
6470 if (NILP (specified_data))
6472 file = x_find_image_file (specified_file);
6473 if (!STRINGP (file))
6475 image_error ("Cannot find image file `%s'", specified_file, Qnil);
6476 return 0;
6479 fp = emacs_fopen (SSDATA (file), "rb");
6480 if (fp == NULL)
6482 image_error ("Cannot open `%s'", file, Qnil);
6483 return 0;
6486 else if (!STRINGP (specified_data))
6488 image_error ("Invalid image data `%s'", specified_data, Qnil);
6489 return 0;
6492 /* Customize libjpeg's error handling to call my_error_exit when an
6493 error is detected. This function will perform a longjmp. */
6494 mgr->cinfo.err = jpeg_std_error (&mgr->pub);
6495 mgr->pub.error_exit = my_error_exit;
6496 if (sys_setjmp (mgr->setjmp_buffer))
6498 switch (mgr->failure_code)
6500 case MY_JPEG_ERROR_EXIT:
6502 char buf[JMSG_LENGTH_MAX];
6503 mgr->cinfo.err->format_message ((j_common_ptr) &mgr->cinfo, buf);
6504 image_error ("Error reading JPEG image `%s': %s", img->spec,
6505 build_string (buf));
6506 break;
6509 case MY_JPEG_INVALID_IMAGE_SIZE:
6510 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
6511 break;
6513 case MY_JPEG_CANNOT_CREATE_X:
6514 break;
6517 /* Close the input file and destroy the JPEG object. */
6518 if (fp)
6519 fclose (fp);
6520 jpeg_destroy_decompress (&mgr->cinfo);
6522 /* If we already have an XImage, free that. */
6523 x_destroy_x_image (ximg);
6525 /* Free pixmap and colors. */
6526 x_clear_image (f, img);
6527 return 0;
6530 /* Create the JPEG decompression object. Let it read from fp.
6531 Read the JPEG image header. */
6532 jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo);
6534 if (NILP (specified_data))
6535 jpeg_file_src (&mgr->cinfo, fp);
6536 else
6537 jpeg_memory_src (&mgr->cinfo, SDATA (specified_data),
6538 SBYTES (specified_data));
6540 jpeg_read_header (&mgr->cinfo, 1);
6542 /* Customize decompression so that color quantization will be used.
6543 Start decompression. */
6544 mgr->cinfo.quantize_colors = 1;
6545 jpeg_start_decompress (&mgr->cinfo);
6546 width = img->width = mgr->cinfo.output_width;
6547 height = img->height = mgr->cinfo.output_height;
6549 if (!check_image_size (f, width, height))
6551 mgr->failure_code = MY_JPEG_INVALID_IMAGE_SIZE;
6552 sys_longjmp (mgr->setjmp_buffer, 1);
6555 /* Create X image and pixmap. */
6556 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
6558 mgr->failure_code = MY_JPEG_CANNOT_CREATE_X;
6559 sys_longjmp (mgr->setjmp_buffer, 1);
6562 /* Allocate colors. When color quantization is used,
6563 mgr->cinfo.actual_number_of_colors has been set with the number of
6564 colors generated, and mgr->cinfo.colormap is a two-dimensional array
6565 of color indices in the range 0..mgr->cinfo.actual_number_of_colors.
6566 No more than 255 colors will be generated. */
6567 USE_SAFE_ALLOCA;
6569 int i, ir, ig, ib;
6571 if (mgr->cinfo.out_color_components > 2)
6572 ir = 0, ig = 1, ib = 2;
6573 else if (mgr->cinfo.out_color_components > 1)
6574 ir = 0, ig = 1, ib = 0;
6575 else
6576 ir = 0, ig = 0, ib = 0;
6578 /* Use the color table mechanism because it handles colors that
6579 cannot be allocated nicely. Such colors will be replaced with
6580 a default color, and we don't have to care about which colors
6581 can be freed safely, and which can't. */
6582 init_color_table ();
6583 SAFE_NALLOCA (colors, 1, mgr->cinfo.actual_number_of_colors);
6585 for (i = 0; i < mgr->cinfo.actual_number_of_colors; ++i)
6587 /* Multiply RGB values with 255 because X expects RGB values
6588 in the range 0..0xffff. */
6589 int r = mgr->cinfo.colormap[ir][i] << 8;
6590 int g = mgr->cinfo.colormap[ig][i] << 8;
6591 int b = mgr->cinfo.colormap[ib][i] << 8;
6592 colors[i] = lookup_rgb_color (f, r, g, b);
6595 #ifdef COLOR_TABLE_SUPPORT
6596 /* Remember those colors actually allocated. */
6597 img->colors = colors_in_color_table (&img->ncolors);
6598 free_color_table ();
6599 #endif /* COLOR_TABLE_SUPPORT */
6602 /* Read pixels. */
6603 row_stride = width * mgr->cinfo.output_components;
6604 buffer = mgr->cinfo.mem->alloc_sarray ((j_common_ptr) &mgr->cinfo,
6605 JPOOL_IMAGE, row_stride, 1);
6606 for (y = 0; y < height; ++y)
6608 jpeg_read_scanlines (&mgr->cinfo, buffer, 1);
6609 for (x = 0; x < mgr->cinfo.output_width; ++x)
6610 XPutPixel (ximg, x, y, colors[buffer[0][x]]);
6613 /* Clean up. */
6614 jpeg_finish_decompress (&mgr->cinfo);
6615 jpeg_destroy_decompress (&mgr->cinfo);
6616 if (fp)
6617 fclose (fp);
6619 /* Maybe fill in the background field while we have ximg handy. */
6620 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
6621 /* Casting avoids a GCC warning. */
6622 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
6624 /* Put ximg into the image. */
6625 image_put_x_image (f, img, ximg, 0);
6626 SAFE_FREE ();
6627 return 1;
6630 static bool
6631 jpeg_load (struct frame *f, struct image *img)
6633 struct my_jpeg_error_mgr mgr;
6634 return jpeg_load_body (f, img, &mgr);
6637 #else /* HAVE_JPEG */
6639 #ifdef HAVE_NS
6640 static bool
6641 jpeg_load (struct frame *f, struct image *img)
6643 return ns_load_image (f, img,
6644 image_spec_value (img->spec, QCfile, NULL),
6645 image_spec_value (img->spec, QCdata, NULL));
6647 #endif /* HAVE_NS */
6649 #endif /* !HAVE_JPEG */
6653 /***********************************************************************
6654 TIFF
6655 ***********************************************************************/
6657 #if defined (HAVE_TIFF) || defined (HAVE_NS)
6659 static bool tiff_image_p (Lisp_Object object);
6660 static bool tiff_load (struct frame *f, struct image *img);
6662 /* Indices of image specification fields in tiff_format, below. */
6664 enum tiff_keyword_index
6666 TIFF_TYPE,
6667 TIFF_DATA,
6668 TIFF_FILE,
6669 TIFF_ASCENT,
6670 TIFF_MARGIN,
6671 TIFF_RELIEF,
6672 TIFF_ALGORITHM,
6673 TIFF_HEURISTIC_MASK,
6674 TIFF_MASK,
6675 TIFF_BACKGROUND,
6676 TIFF_INDEX,
6677 TIFF_LAST
6680 /* Vector of image_keyword structures describing the format
6681 of valid user-defined image specifications. */
6683 static const struct image_keyword tiff_format[TIFF_LAST] =
6685 {":type", IMAGE_SYMBOL_VALUE, 1},
6686 {":data", IMAGE_STRING_VALUE, 0},
6687 {":file", IMAGE_STRING_VALUE, 0},
6688 {":ascent", IMAGE_ASCENT_VALUE, 0},
6689 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
6690 {":relief", IMAGE_INTEGER_VALUE, 0},
6691 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6692 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6693 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6694 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
6695 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}
6698 #if defined HAVE_NTGUI && defined WINDOWSNT
6699 static bool init_tiff_functions (void);
6700 #else
6701 #define init_tiff_functions NULL
6702 #endif
6704 /* Structure describing the image type `tiff'. */
6706 static struct image_type tiff_type =
6708 XSYMBOL_INIT (Qtiff),
6709 tiff_image_p,
6710 tiff_load,
6711 x_clear_image,
6712 init_tiff_functions,
6713 NULL
6716 /* Return true if OBJECT is a valid TIFF image specification. */
6718 static bool
6719 tiff_image_p (Lisp_Object object)
6721 struct image_keyword fmt[TIFF_LAST];
6722 memcpy (fmt, tiff_format, sizeof fmt);
6724 if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff))
6725 return 0;
6727 /* Must specify either the :data or :file keyword. */
6728 return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1;
6731 #endif /* HAVE_TIFF || HAVE_NS */
6733 #ifdef HAVE_TIFF
6735 # include <tiffio.h>
6737 # ifdef WINDOWSNT
6739 /* TIFF library details. */
6740 DEF_DLL_FN (TIFFErrorHandler, TIFFSetErrorHandler, (TIFFErrorHandler));
6741 DEF_DLL_FN (TIFFErrorHandler, TIFFSetWarningHandler, (TIFFErrorHandler));
6742 DEF_DLL_FN (TIFF *, TIFFOpen, (const char *, const char *));
6743 DEF_DLL_FN (TIFF *, TIFFClientOpen,
6744 (const char *, const char *, thandle_t, TIFFReadWriteProc,
6745 TIFFReadWriteProc, TIFFSeekProc, TIFFCloseProc, TIFFSizeProc,
6746 TIFFMapFileProc, TIFFUnmapFileProc));
6747 DEF_DLL_FN (int, TIFFGetField, (TIFF *, ttag_t, ...));
6748 DEF_DLL_FN (int, TIFFReadRGBAImage, (TIFF *, uint32, uint32, uint32 *, int));
6749 DEF_DLL_FN (void, TIFFClose, (TIFF *));
6750 DEF_DLL_FN (int, TIFFSetDirectory, (TIFF *, tdir_t));
6752 static bool
6753 init_tiff_functions (void)
6755 HMODULE library;
6757 if (!(library = w32_delayed_load (Qtiff)))
6758 return 0;
6760 LOAD_DLL_FN (library, TIFFSetErrorHandler);
6761 LOAD_DLL_FN (library, TIFFSetWarningHandler);
6762 LOAD_DLL_FN (library, TIFFOpen);
6763 LOAD_DLL_FN (library, TIFFClientOpen);
6764 LOAD_DLL_FN (library, TIFFGetField);
6765 LOAD_DLL_FN (library, TIFFReadRGBAImage);
6766 LOAD_DLL_FN (library, TIFFClose);
6767 LOAD_DLL_FN (library, TIFFSetDirectory);
6768 return 1;
6771 # undef TIFFClientOpen
6772 # undef TIFFClose
6773 # undef TIFFGetField
6774 # undef TIFFOpen
6775 # undef TIFFReadRGBAImage
6776 # undef TIFFSetDirectory
6777 # undef TIFFSetErrorHandler
6778 # undef TIFFSetWarningHandler
6780 # define TIFFClientOpen fn_TIFFClientOpen
6781 # define TIFFClose fn_TIFFClose
6782 # define TIFFGetField fn_TIFFGetField
6783 # define TIFFOpen fn_TIFFOpen
6784 # define TIFFReadRGBAImage fn_TIFFReadRGBAImage
6785 # define TIFFSetDirectory fn_TIFFSetDirectory
6786 # define TIFFSetErrorHandler fn_TIFFSetErrorHandler
6787 # define TIFFSetWarningHandler fn_TIFFSetWarningHandler
6789 # endif /* WINDOWSNT */
6792 /* Reading from a memory buffer for TIFF images Based on the PNG
6793 memory source, but we have to provide a lot of extra functions.
6794 Blah.
6796 We really only need to implement read and seek, but I am not
6797 convinced that the TIFF library is smart enough not to destroy
6798 itself if we only hand it the function pointers we need to
6799 override. */
6801 typedef struct
6803 unsigned char *bytes;
6804 ptrdiff_t len;
6805 ptrdiff_t index;
6807 tiff_memory_source;
6809 static tsize_t
6810 tiff_read_from_memory (thandle_t data, tdata_t buf, tsize_t size)
6812 tiff_memory_source *src = (tiff_memory_source *) data;
6814 size = min (size, src->len - src->index);
6815 memcpy (buf, src->bytes + src->index, size);
6816 src->index += size;
6817 return size;
6820 static tsize_t
6821 tiff_write_from_memory (thandle_t data, tdata_t buf, tsize_t size)
6823 return -1;
6826 static toff_t
6827 tiff_seek_in_memory (thandle_t data, toff_t off, int whence)
6829 tiff_memory_source *src = (tiff_memory_source *) data;
6830 ptrdiff_t idx;
6832 switch (whence)
6834 case SEEK_SET: /* Go from beginning of source. */
6835 idx = off;
6836 break;
6838 case SEEK_END: /* Go from end of source. */
6839 idx = src->len + off;
6840 break;
6842 case SEEK_CUR: /* Go from current position. */
6843 idx = src->index + off;
6844 break;
6846 default: /* Invalid `whence'. */
6847 return -1;
6850 if (idx > src->len || idx < 0)
6851 return -1;
6853 src->index = idx;
6854 return src->index;
6857 static int
6858 tiff_close_memory (thandle_t data)
6860 /* NOOP */
6861 return 0;
6864 static int
6865 tiff_mmap_memory (thandle_t data, tdata_t *pbase, toff_t *psize)
6867 /* It is already _IN_ memory. */
6868 return 0;
6871 static void
6872 tiff_unmap_memory (thandle_t data, tdata_t base, toff_t size)
6874 /* We don't need to do this. */
6877 static toff_t
6878 tiff_size_of_memory (thandle_t data)
6880 return ((tiff_memory_source *) data)->len;
6883 /* GCC 3.x on x86 Windows targets has a bug that triggers an internal
6884 compiler error compiling tiff_handler, see Bugzilla bug #17406
6885 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17406). Declaring
6886 this function as external works around that problem. */
6887 # if defined (__MINGW32__) && __GNUC__ == 3
6888 # define MINGW_STATIC
6889 # else
6890 # define MINGW_STATIC static
6891 # endif
6893 MINGW_STATIC void
6894 tiff_handler (const char *, const char *, const char *, va_list)
6895 ATTRIBUTE_FORMAT_PRINTF (3, 0);
6896 MINGW_STATIC void
6897 tiff_handler (const char *log_format, const char *title,
6898 const char *format, va_list ap)
6900 /* doprnt is not suitable here, as TIFF handlers are called from
6901 libtiff and are passed arbitrary printf directives. Instead, use
6902 vsnprintf, taking care to be portable to nonstandard environments
6903 where vsnprintf returns -1 on buffer overflow. Since it's just a
6904 log entry, it's OK to truncate it. */
6905 char buf[4000];
6906 int len = vsnprintf (buf, sizeof buf, format, ap);
6907 add_to_log (log_format, build_string (title),
6908 make_string (buf, max (0, min (len, sizeof buf - 1))));
6910 # undef MINGW_STATIC
6912 static void tiff_error_handler (const char *, const char *, va_list)
6913 ATTRIBUTE_FORMAT_PRINTF (2, 0);
6914 static void
6915 tiff_error_handler (const char *title, const char *format, va_list ap)
6917 tiff_handler ("TIFF error: %s %s", title, format, ap);
6921 static void tiff_warning_handler (const char *, const char *, va_list)
6922 ATTRIBUTE_FORMAT_PRINTF (2, 0);
6923 static void
6924 tiff_warning_handler (const char *title, const char *format, va_list ap)
6926 tiff_handler ("TIFF warning: %s %s", title, format, ap);
6930 /* Load TIFF image IMG for use on frame F. Value is true if
6931 successful. */
6933 static bool
6934 tiff_load (struct frame *f, struct image *img)
6936 Lisp_Object file, specified_file;
6937 Lisp_Object specified_data;
6938 TIFF *tiff;
6939 int width, height, x, y, count;
6940 uint32 *buf;
6941 int rc;
6942 XImagePtr ximg;
6943 tiff_memory_source memsrc;
6944 Lisp_Object image;
6946 specified_file = image_spec_value (img->spec, QCfile, NULL);
6947 specified_data = image_spec_value (img->spec, QCdata, NULL);
6949 TIFFSetErrorHandler ((TIFFErrorHandler) tiff_error_handler);
6950 TIFFSetWarningHandler ((TIFFErrorHandler) tiff_warning_handler);
6952 if (NILP (specified_data))
6954 /* Read from a file */
6955 file = x_find_image_file (specified_file);
6956 if (!STRINGP (file))
6958 image_error ("Cannot find image file `%s'", specified_file, Qnil);
6959 return 0;
6961 # ifdef WINDOWSNT
6962 file = ansi_encode_filename (file);
6963 # endif
6965 /* Try to open the image file. */
6966 tiff = TIFFOpen (SSDATA (file), "r");
6967 if (tiff == NULL)
6969 image_error ("Cannot open `%s'", file, Qnil);
6970 return 0;
6973 else
6975 if (!STRINGP (specified_data))
6977 image_error ("Invalid image data `%s'", specified_data, Qnil);
6978 return 0;
6981 /* Memory source! */
6982 memsrc.bytes = SDATA (specified_data);
6983 memsrc.len = SBYTES (specified_data);
6984 memsrc.index = 0;
6986 tiff = TIFFClientOpen ("memory_source", "r", (thandle_t)&memsrc,
6987 tiff_read_from_memory,
6988 tiff_write_from_memory,
6989 tiff_seek_in_memory,
6990 tiff_close_memory,
6991 tiff_size_of_memory,
6992 tiff_mmap_memory,
6993 tiff_unmap_memory);
6995 if (!tiff)
6997 image_error ("Cannot open memory source for `%s'", img->spec, Qnil);
6998 return 0;
7002 image = image_spec_value (img->spec, QCindex, NULL);
7003 if (INTEGERP (image))
7005 EMACS_INT ino = XFASTINT (image);
7006 if (! (TYPE_MINIMUM (tdir_t) <= ino && ino <= TYPE_MAXIMUM (tdir_t)
7007 && TIFFSetDirectory (tiff, ino)))
7009 image_error ("Invalid image number `%s' in image `%s'",
7010 image, img->spec);
7011 TIFFClose (tiff);
7012 return 0;
7016 /* Get width and height of the image, and allocate a raster buffer
7017 of width x height 32-bit values. */
7018 TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
7019 TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
7021 if (!check_image_size (f, width, height))
7023 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
7024 TIFFClose (tiff);
7025 return 0;
7028 /* Create the X image and pixmap. */
7029 if (! (height <= min (PTRDIFF_MAX, SIZE_MAX) / sizeof *buf / width
7030 && image_create_x_image_and_pixmap (f, img, width, height, 0,
7031 &ximg, 0)))
7033 TIFFClose (tiff);
7034 return 0;
7037 buf = xmalloc (sizeof *buf * width * height);
7039 rc = TIFFReadRGBAImage (tiff, width, height, buf, 0);
7041 /* Count the number of images in the file. */
7042 for (count = 1; TIFFSetDirectory (tiff, count); count++)
7043 continue;
7045 if (count > 1)
7046 img->lisp_data = Fcons (Qcount,
7047 Fcons (make_number (count),
7048 img->lisp_data));
7050 TIFFClose (tiff);
7051 if (!rc)
7053 image_error ("Error reading TIFF image `%s'", img->spec, Qnil);
7054 xfree (buf);
7055 return 0;
7058 /* Initialize the color table. */
7059 init_color_table ();
7061 /* Process the pixel raster. Origin is in the lower-left corner. */
7062 for (y = 0; y < height; ++y)
7064 uint32 *row = buf + y * width;
7066 for (x = 0; x < width; ++x)
7068 uint32 abgr = row[x];
7069 int r = TIFFGetR (abgr) << 8;
7070 int g = TIFFGetG (abgr) << 8;
7071 int b = TIFFGetB (abgr) << 8;
7072 XPutPixel (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b));
7076 # ifdef COLOR_TABLE_SUPPORT
7077 /* Remember the colors allocated for the image. Free the color table. */
7078 img->colors = colors_in_color_table (&img->ncolors);
7079 free_color_table ();
7080 # endif /* COLOR_TABLE_SUPPORT */
7082 img->width = width;
7083 img->height = height;
7085 /* Maybe fill in the background field while we have ximg handy. */
7086 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7087 /* Casting avoids a GCC warning on W32. */
7088 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
7090 /* Put ximg into the image. */
7091 image_put_x_image (f, img, ximg, 0);
7092 xfree (buf);
7094 return 1;
7097 #elif defined HAVE_NS
7099 static bool
7100 tiff_load (struct frame *f, struct image *img)
7102 return ns_load_image (f, img,
7103 image_spec_value (img->spec, QCfile, NULL),
7104 image_spec_value (img->spec, QCdata, NULL));
7107 #endif
7111 /***********************************************************************
7113 ***********************************************************************/
7115 #if defined (HAVE_GIF) || defined (HAVE_NS)
7117 static bool gif_image_p (Lisp_Object object);
7118 static bool gif_load (struct frame *f, struct image *img);
7119 static void gif_clear_image (struct frame *f, struct image *img);
7121 /* Indices of image specification fields in gif_format, below. */
7123 enum gif_keyword_index
7125 GIF_TYPE,
7126 GIF_DATA,
7127 GIF_FILE,
7128 GIF_ASCENT,
7129 GIF_MARGIN,
7130 GIF_RELIEF,
7131 GIF_ALGORITHM,
7132 GIF_HEURISTIC_MASK,
7133 GIF_MASK,
7134 GIF_IMAGE,
7135 GIF_BACKGROUND,
7136 GIF_LAST
7139 /* Vector of image_keyword structures describing the format
7140 of valid user-defined image specifications. */
7142 static const struct image_keyword gif_format[GIF_LAST] =
7144 {":type", IMAGE_SYMBOL_VALUE, 1},
7145 {":data", IMAGE_STRING_VALUE, 0},
7146 {":file", IMAGE_STRING_VALUE, 0},
7147 {":ascent", IMAGE_ASCENT_VALUE, 0},
7148 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
7149 {":relief", IMAGE_INTEGER_VALUE, 0},
7150 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7151 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7152 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7153 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
7154 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
7157 #if defined HAVE_NTGUI && defined WINDOWSNT
7158 static bool init_gif_functions (void);
7159 #else
7160 #define init_gif_functions NULL
7161 #endif
7163 /* Structure describing the image type `gif'. */
7165 static struct image_type gif_type =
7167 XSYMBOL_INIT (Qgif),
7168 gif_image_p,
7169 gif_load,
7170 gif_clear_image,
7171 init_gif_functions,
7172 NULL
7175 /* Free X resources of GIF image IMG which is used on frame F. */
7177 static void
7178 gif_clear_image (struct frame *f, struct image *img)
7180 img->lisp_data = Qnil;
7181 x_clear_image (f, img);
7184 /* Return true if OBJECT is a valid GIF image specification. */
7186 static bool
7187 gif_image_p (Lisp_Object object)
7189 struct image_keyword fmt[GIF_LAST];
7190 memcpy (fmt, gif_format, sizeof fmt);
7192 if (!parse_image_spec (object, fmt, GIF_LAST, Qgif))
7193 return 0;
7195 /* Must specify either the :data or :file keyword. */
7196 return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1;
7199 #endif /* HAVE_GIF */
7201 #ifdef HAVE_GIF
7203 # ifdef HAVE_NTGUI
7205 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
7206 Undefine before redefining to avoid a preprocessor warning. */
7207 # ifdef DrawText
7208 # undef DrawText
7209 # endif
7210 /* avoid conflict with QuickdrawText.h */
7211 # define DrawText gif_DrawText
7212 # include <gif_lib.h>
7213 # undef DrawText
7215 /* Giflib before 5.0 didn't define these macros (used only if HAVE_NTGUI). */
7216 # ifndef GIFLIB_MINOR
7217 # define GIFLIB_MINOR 0
7218 # endif
7219 # ifndef GIFLIB_RELEASE
7220 # define GIFLIB_RELEASE 0
7221 # endif
7223 # else /* HAVE_NTGUI */
7225 # include <gif_lib.h>
7227 # endif /* HAVE_NTGUI */
7229 /* Giflib before 5.0 didn't define these macros. */
7230 # ifndef GIFLIB_MAJOR
7231 # define GIFLIB_MAJOR 4
7232 # endif
7234 # ifdef WINDOWSNT
7236 /* GIF library details. */
7237 # if 5 < GIFLIB_MAJOR + (1 <= GIFLIB_MINOR)
7238 DEF_DLL_FN (int, DGifCloseFile, (GifFileType *, int *));
7239 # else
7240 DEF_DLL_FN (int, DGifCloseFile, (GifFileType *));
7241 # endif
7242 DEF_DLL_FN (int, DGifSlurp, (GifFileType *));
7243 # if GIFLIB_MAJOR < 5
7244 DEF_DLL_FN (GifFileType *, DGifOpen, (void *, InputFunc));
7245 DEF_DLL_FN (GifFileType *, DGifOpenFileName, (const char *));
7246 # else
7247 DEF_DLL_FN (GifFileType *, DGifOpen, (void *, InputFunc, int *));
7248 DEF_DLL_FN (GifFileType *, DGifOpenFileName, (const char *, int *));
7249 DEF_DLL_FN (char *, GifErrorString, (int));
7250 # endif
7252 static bool
7253 init_gif_functions (void)
7255 HMODULE library;
7257 if (!(library = w32_delayed_load (Qgif)))
7258 return 0;
7260 LOAD_DLL_FN (library, DGifCloseFile);
7261 LOAD_DLL_FN (library, DGifSlurp);
7262 LOAD_DLL_FN (library, DGifOpen);
7263 LOAD_DLL_FN (library, DGifOpenFileName);
7264 # if GIFLIB_MAJOR >= 5
7265 LOAD_DLL_FN (library, GifErrorString);
7266 # endif
7267 return 1;
7270 # undef DGifCloseFile
7271 # undef DGifOpen
7272 # undef DGifOpenFileName
7273 # undef DGifSlurp
7274 # undef GifErrorString
7276 # define DGifCloseFile fn_DGifCloseFile
7277 # define DGifOpen fn_DGifOpen
7278 # define DGifOpenFileName fn_DGifOpenFileName
7279 # define DGifSlurp fn_DGifSlurp
7280 # define GifErrorString fn_GifErrorString
7282 # endif /* WINDOWSNT */
7284 /* Reading a GIF image from memory
7285 Based on the PNG memory stuff to a certain extent. */
7287 typedef struct
7289 unsigned char *bytes;
7290 ptrdiff_t len;
7291 ptrdiff_t index;
7293 gif_memory_source;
7295 /* Make the current memory source available to gif_read_from_memory.
7296 It's done this way because not all versions of libungif support
7297 a UserData field in the GifFileType structure. */
7298 static gif_memory_source *current_gif_memory_src;
7300 static int
7301 gif_read_from_memory (GifFileType *file, GifByteType *buf, int len)
7303 gif_memory_source *src = current_gif_memory_src;
7305 if (len > src->len - src->index)
7306 return -1;
7308 memcpy (buf, src->bytes + src->index, len);
7309 src->index += len;
7310 return len;
7313 static int
7314 gif_close (GifFileType *gif, int *err)
7316 int retval;
7318 #if 5 < GIFLIB_MAJOR + (1 <= GIFLIB_MINOR)
7319 retval = DGifCloseFile (gif, err);
7320 #else
7321 retval = DGifCloseFile (gif);
7322 #if GIFLIB_MAJOR >= 5
7323 if (err)
7324 *err = gif->Error;
7325 #endif
7326 #endif
7327 return retval;
7330 /* Load GIF image IMG for use on frame F. Value is true if
7331 successful. */
7333 static const int interlace_start[] = {0, 4, 2, 1};
7334 static const int interlace_increment[] = {8, 8, 4, 2};
7336 #define GIF_LOCAL_DESCRIPTOR_EXTENSION 249
7338 static bool
7339 gif_load (struct frame *f, struct image *img)
7341 Lisp_Object file;
7342 int rc, width, height, x, y, i, j;
7343 XImagePtr ximg;
7344 ColorMapObject *gif_color_map;
7345 unsigned long pixel_colors[256];
7346 GifFileType *gif;
7347 gif_memory_source memsrc;
7348 Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL);
7349 Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
7350 Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL);
7351 unsigned long bgcolor = 0;
7352 EMACS_INT idx;
7353 int gif_err;
7355 if (NILP (specified_data))
7357 file = x_find_image_file (specified_file);
7358 if (!STRINGP (file))
7360 image_error ("Cannot find image file `%s'", specified_file, Qnil);
7361 return 0;
7363 #ifdef WINDOWSNT
7364 file = ansi_encode_filename (file);
7365 #endif
7367 /* Open the GIF file. */
7368 #if GIFLIB_MAJOR < 5
7369 gif = DGifOpenFileName (SSDATA (file));
7370 if (gif == NULL)
7372 image_error ("Cannot open `%s'", file, Qnil);
7373 return 0;
7375 #else
7376 gif = DGifOpenFileName (SSDATA (file), &gif_err);
7377 if (gif == NULL)
7379 image_error ("Cannot open `%s': %s",
7380 file, build_string (GifErrorString (gif_err)));
7381 return 0;
7383 #endif
7385 else
7387 if (!STRINGP (specified_data))
7389 image_error ("Invalid image data `%s'", specified_data, Qnil);
7390 return 0;
7393 /* Read from memory! */
7394 current_gif_memory_src = &memsrc;
7395 memsrc.bytes = SDATA (specified_data);
7396 memsrc.len = SBYTES (specified_data);
7397 memsrc.index = 0;
7399 #if GIFLIB_MAJOR < 5
7400 gif = DGifOpen (&memsrc, gif_read_from_memory);
7401 if (!gif)
7403 image_error ("Cannot open memory source `%s'", img->spec, Qnil);
7404 return 0;
7406 #else
7407 gif = DGifOpen (&memsrc, gif_read_from_memory, &gif_err);
7408 if (!gif)
7410 image_error ("Cannot open memory source `%s': %s",
7411 img->spec, build_string (GifErrorString (gif_err)));
7412 return 0;
7414 #endif
7417 /* Before reading entire contents, check the declared image size. */
7418 if (!check_image_size (f, gif->SWidth, gif->SHeight))
7420 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
7421 gif_close (gif, NULL);
7422 return 0;
7425 /* Read entire contents. */
7426 rc = DGifSlurp (gif);
7427 if (rc == GIF_ERROR || gif->ImageCount <= 0)
7429 image_error ("Error reading `%s'", img->spec, Qnil);
7430 gif_close (gif, NULL);
7431 return 0;
7434 /* Which sub-image are we to display? */
7436 Lisp_Object image_number = image_spec_value (img->spec, QCindex, NULL);
7437 idx = INTEGERP (image_number) ? XFASTINT (image_number) : 0;
7438 if (idx < 0 || idx >= gif->ImageCount)
7440 image_error ("Invalid image number `%s' in image `%s'",
7441 image_number, img->spec);
7442 gif_close (gif, NULL);
7443 return 0;
7447 width = img->width = gif->SWidth;
7448 height = img->height = gif->SHeight;
7450 img->corners[TOP_CORNER] = gif->SavedImages[0].ImageDesc.Top;
7451 img->corners[LEFT_CORNER] = gif->SavedImages[0].ImageDesc.Left;
7452 img->corners[BOT_CORNER]
7453 = img->corners[TOP_CORNER] + gif->SavedImages[0].ImageDesc.Height;
7454 img->corners[RIGHT_CORNER]
7455 = img->corners[LEFT_CORNER] + gif->SavedImages[0].ImageDesc.Width;
7457 if (!check_image_size (f, width, height))
7459 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
7460 gif_close (gif, NULL);
7461 return 0;
7464 /* Check that the selected subimages fit. It's not clear whether
7465 the GIF spec requires this, but Emacs can crash if they don't fit. */
7466 for (j = 0; j <= idx; ++j)
7468 struct SavedImage *subimage = gif->SavedImages + j;
7469 int subimg_width = subimage->ImageDesc.Width;
7470 int subimg_height = subimage->ImageDesc.Height;
7471 int subimg_top = subimage->ImageDesc.Top;
7472 int subimg_left = subimage->ImageDesc.Left;
7473 if (! (0 <= subimg_width && 0 <= subimg_height
7474 && 0 <= subimg_top && subimg_top <= height - subimg_height
7475 && 0 <= subimg_left && subimg_left <= width - subimg_width))
7477 image_error ("Subimage does not fit in image", Qnil, Qnil);
7478 gif_close (gif, NULL);
7479 return 0;
7483 /* Create the X image and pixmap. */
7484 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
7486 gif_close (gif, NULL);
7487 return 0;
7490 /* Clear the part of the screen image not covered by the image.
7491 Full animated GIF support requires more here (see the gif89 spec,
7492 disposal methods). Let's simply assume that the part not covered
7493 by a sub-image is in the frame's background color. */
7494 for (y = 0; y < img->corners[TOP_CORNER]; ++y)
7495 for (x = 0; x < width; ++x)
7496 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7498 for (y = img->corners[BOT_CORNER]; y < height; ++y)
7499 for (x = 0; x < width; ++x)
7500 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7502 for (y = img->corners[TOP_CORNER]; y < img->corners[BOT_CORNER]; ++y)
7504 for (x = 0; x < img->corners[LEFT_CORNER]; ++x)
7505 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7506 for (x = img->corners[RIGHT_CORNER]; x < width; ++x)
7507 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7510 /* Read the GIF image into the X image. */
7512 /* FIXME: With the current implementation, loading an animated gif
7513 is quadratic in the number of animation frames, since each frame
7514 is a separate struct image. We must provide a way for a single
7515 gif_load call to construct and save all animation frames. */
7517 init_color_table ();
7518 if (STRINGP (specified_bg))
7519 bgcolor = x_alloc_image_color (f, img, specified_bg,
7520 FRAME_BACKGROUND_PIXEL (f));
7521 for (j = 0; j <= idx; ++j)
7523 /* We use a local variable `raster' here because RasterBits is a
7524 char *, which invites problems with bytes >= 0x80. */
7525 struct SavedImage *subimage = gif->SavedImages + j;
7526 unsigned char *raster = (unsigned char *) subimage->RasterBits;
7527 int transparency_color_index = -1;
7528 int disposal = 0;
7529 int subimg_width = subimage->ImageDesc.Width;
7530 int subimg_height = subimage->ImageDesc.Height;
7531 int subimg_top = subimage->ImageDesc.Top;
7532 int subimg_left = subimage->ImageDesc.Left;
7534 /* Find the Graphic Control Extension block for this sub-image.
7535 Extract the disposal method and transparency color. */
7536 for (i = 0; i < subimage->ExtensionBlockCount; i++)
7538 ExtensionBlock *extblock = subimage->ExtensionBlocks + i;
7540 if ((extblock->Function == GIF_LOCAL_DESCRIPTOR_EXTENSION)
7541 && extblock->ByteCount == 4
7542 && extblock->Bytes[0] & 1)
7544 /* From gif89a spec: 1 = "keep in place", 2 = "restore
7545 to background". Treat any other value like 2. */
7546 disposal = (extblock->Bytes[0] >> 2) & 7;
7547 transparency_color_index = (unsigned char) extblock->Bytes[3];
7548 break;
7552 /* We can't "keep in place" the first subimage. */
7553 if (j == 0)
7554 disposal = 2;
7556 /* For disposal == 0, the spec says "No disposal specified. The
7557 decoder is not required to take any action." In practice, it
7558 seems we need to treat this like "keep in place", see e.g.
7559 http://upload.wikimedia.org/wikipedia/commons/3/37/Clock.gif */
7560 if (disposal == 0)
7561 disposal = 1;
7563 /* Allocate subimage colors. */
7564 memset (pixel_colors, 0, sizeof pixel_colors);
7565 gif_color_map = subimage->ImageDesc.ColorMap;
7566 if (!gif_color_map)
7567 gif_color_map = gif->SColorMap;
7569 if (gif_color_map)
7570 for (i = 0; i < gif_color_map->ColorCount; ++i)
7572 if (transparency_color_index == i)
7573 pixel_colors[i] = STRINGP (specified_bg)
7574 ? bgcolor : FRAME_BACKGROUND_PIXEL (f);
7575 else
7577 int r = gif_color_map->Colors[i].Red << 8;
7578 int g = gif_color_map->Colors[i].Green << 8;
7579 int b = gif_color_map->Colors[i].Blue << 8;
7580 pixel_colors[i] = lookup_rgb_color (f, r, g, b);
7584 /* Apply the pixel values. */
7585 if (GIFLIB_MAJOR < 5 && gif->SavedImages[j].ImageDesc.Interlace)
7587 int row, pass;
7589 for (y = 0, row = interlace_start[0], pass = 0;
7590 y < subimg_height;
7591 y++, row += interlace_increment[pass])
7593 while (subimg_height <= row)
7594 row = interlace_start[++pass];
7596 for (x = 0; x < subimg_width; x++)
7598 int c = raster[y * subimg_width + x];
7599 if (transparency_color_index != c || disposal != 1)
7600 XPutPixel (ximg, x + subimg_left, row + subimg_top,
7601 pixel_colors[c]);
7605 else
7607 for (y = 0; y < subimg_height; ++y)
7608 for (x = 0; x < subimg_width; ++x)
7610 int c = raster[y * subimg_width + x];
7611 if (transparency_color_index != c || disposal != 1)
7612 XPutPixel (ximg, x + subimg_left, y + subimg_top,
7613 pixel_colors[c]);
7618 #ifdef COLOR_TABLE_SUPPORT
7619 img->colors = colors_in_color_table (&img->ncolors);
7620 free_color_table ();
7621 #endif /* COLOR_TABLE_SUPPORT */
7623 /* Save GIF image extension data for `image-metadata'.
7624 Format is (count IMAGES extension-data (FUNCTION "BYTES" ...)). */
7625 img->lisp_data = Qnil;
7626 if (gif->SavedImages[idx].ExtensionBlockCount > 0)
7628 int delay = 0;
7629 ExtensionBlock *ext = gif->SavedImages[idx].ExtensionBlocks;
7630 for (i = 0; i < gif->SavedImages[idx].ExtensionBlockCount; i++, ext++)
7631 /* Append (... FUNCTION "BYTES") */
7633 img->lisp_data
7634 = Fcons (make_number (ext->Function),
7635 Fcons (make_unibyte_string (ext->Bytes, ext->ByteCount),
7636 img->lisp_data));
7637 if (ext->Function == GIF_LOCAL_DESCRIPTOR_EXTENSION
7638 && ext->ByteCount == 4)
7640 delay = ext->Bytes[2] << CHAR_BIT;
7641 delay |= ext->Bytes[1];
7644 img->lisp_data = list2 (Qextension_data, img->lisp_data);
7645 if (delay)
7646 img->lisp_data
7647 = Fcons (Qdelay,
7648 Fcons (make_float (delay / 100.0),
7649 img->lisp_data));
7652 if (gif->ImageCount > 1)
7653 img->lisp_data = Fcons (Qcount,
7654 Fcons (make_number (gif->ImageCount),
7655 img->lisp_data));
7657 if (gif_close (gif, &gif_err) == GIF_ERROR)
7659 #if 5 <= GIFLIB_MAJOR
7660 char *error_text = GifErrorString (gif_err);
7662 if (error_text)
7663 image_error ("Error closing `%s': %s",
7664 img->spec, build_string (error_text));
7665 #else
7666 image_error ("Error closing `%s'", img->spec, Qnil);
7667 #endif
7670 /* Maybe fill in the background field while we have ximg handy. */
7671 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7672 /* Casting avoids a GCC warning. */
7673 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
7675 /* Put ximg into the image. */
7676 image_put_x_image (f, img, ximg, 0);
7678 return 1;
7681 #else /* !HAVE_GIF */
7683 #ifdef HAVE_NS
7684 static bool
7685 gif_load (struct frame *f, struct image *img)
7687 return ns_load_image (f, img,
7688 image_spec_value (img->spec, QCfile, NULL),
7689 image_spec_value (img->spec, QCdata, NULL));
7691 #endif /* HAVE_NS */
7693 #endif /* HAVE_GIF */
7696 #ifdef HAVE_IMAGEMAGICK
7698 /***********************************************************************
7699 ImageMagick
7700 ***********************************************************************/
7702 /* Scale an image size by returning SIZE / DIVISOR * MULTIPLIER,
7703 safely rounded and clipped to int range. */
7705 static int
7706 scale_image_size (int size, size_t divisor, size_t multiplier)
7708 if (divisor != 0)
7710 double s = size;
7711 double scaled = s * multiplier / divisor + 0.5;
7712 if (scaled < INT_MAX)
7713 return scaled;
7715 return INT_MAX;
7718 /* Compute the desired size of an image with native size WIDTH x HEIGHT.
7719 Use SPEC to deduce the size. Store the desired size into
7720 *D_WIDTH x *D_HEIGHT. Store -1 x -1 if the native size is OK. */
7721 static void
7722 compute_image_size (size_t width, size_t height,
7723 Lisp_Object spec,
7724 int *d_width, int *d_height)
7726 Lisp_Object value;
7727 int desired_width, desired_height;
7729 /* If width and/or height is set in the display spec assume we want
7730 to scale to those values. If either h or w is unspecified, the
7731 unspecified should be calculated from the specified to preserve
7732 aspect ratio. */
7733 value = image_spec_value (spec, QCwidth, NULL);
7734 desired_width = NATNUMP (value) ? min (XFASTINT (value), INT_MAX) : -1;
7735 value = image_spec_value (spec, QCheight, NULL);
7736 desired_height = NATNUMP (value) ? min (XFASTINT (value), INT_MAX) : -1;
7738 if (desired_width == -1)
7740 value = image_spec_value (spec, QCmax_width, NULL);
7741 if (NATNUMP (value))
7743 int max_width = min (XFASTINT (value), INT_MAX);
7744 if (max_width < width)
7746 /* The image is wider than :max-width. */
7747 desired_width = max_width;
7748 if (desired_height == -1)
7750 desired_height = scale_image_size (desired_width,
7751 width, height);
7752 value = image_spec_value (spec, QCmax_height, NULL);
7753 if (NATNUMP (value))
7755 int max_height = min (XFASTINT (value), INT_MAX);
7756 if (max_height < desired_height)
7758 desired_height = max_height;
7759 desired_width = scale_image_size (desired_height,
7760 height, width);
7768 if (desired_height == -1)
7770 value = image_spec_value (spec, QCmax_height, NULL);
7771 if (NATNUMP (value))
7773 int max_height = min (XFASTINT (value), INT_MAX);
7774 if (max_height < height)
7775 desired_height = max_height;
7779 if (desired_width != -1 && desired_height == -1)
7780 /* w known, calculate h. */
7781 desired_height = scale_image_size (desired_width, width, height);
7783 if (desired_width == -1 && desired_height != -1)
7784 /* h known, calculate w. */
7785 desired_width = scale_image_size (desired_height, height, width);
7787 *d_width = desired_width;
7788 *d_height = desired_height;
7791 static bool imagemagick_image_p (Lisp_Object);
7792 static bool imagemagick_load (struct frame *, struct image *);
7793 static void imagemagick_clear_image (struct frame *, struct image *);
7795 /* Indices of image specification fields in imagemagick_format. */
7797 enum imagemagick_keyword_index
7799 IMAGEMAGICK_TYPE,
7800 IMAGEMAGICK_DATA,
7801 IMAGEMAGICK_FILE,
7802 IMAGEMAGICK_ASCENT,
7803 IMAGEMAGICK_MARGIN,
7804 IMAGEMAGICK_RELIEF,
7805 IMAGEMAGICK_ALGORITHM,
7806 IMAGEMAGICK_HEURISTIC_MASK,
7807 IMAGEMAGICK_MASK,
7808 IMAGEMAGICK_BACKGROUND,
7809 IMAGEMAGICK_HEIGHT,
7810 IMAGEMAGICK_WIDTH,
7811 IMAGEMAGICK_MAX_HEIGHT,
7812 IMAGEMAGICK_MAX_WIDTH,
7813 IMAGEMAGICK_FORMAT,
7814 IMAGEMAGICK_ROTATION,
7815 IMAGEMAGICK_CROP,
7816 IMAGEMAGICK_LAST
7819 /* Vector of image_keyword structures describing the format
7820 of valid user-defined image specifications. */
7822 static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
7824 {":type", IMAGE_SYMBOL_VALUE, 1},
7825 {":data", IMAGE_STRING_VALUE, 0},
7826 {":file", IMAGE_STRING_VALUE, 0},
7827 {":ascent", IMAGE_ASCENT_VALUE, 0},
7828 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
7829 {":relief", IMAGE_INTEGER_VALUE, 0},
7830 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7831 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7832 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7833 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
7834 {":height", IMAGE_INTEGER_VALUE, 0},
7835 {":width", IMAGE_INTEGER_VALUE, 0},
7836 {":max-height", IMAGE_INTEGER_VALUE, 0},
7837 {":max-width", IMAGE_INTEGER_VALUE, 0},
7838 {":format", IMAGE_SYMBOL_VALUE, 0},
7839 {":rotation", IMAGE_NUMBER_VALUE, 0},
7840 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
7843 #if defined HAVE_NTGUI && defined WINDOWSNT
7844 static bool init_imagemagick_functions (void);
7845 #else
7846 #define init_imagemagick_functions NULL
7847 #endif
7849 /* Structure describing the image type for any image handled via
7850 ImageMagick. */
7852 static struct image_type imagemagick_type =
7854 XSYMBOL_INIT (Qimagemagick),
7855 imagemagick_image_p,
7856 imagemagick_load,
7857 imagemagick_clear_image,
7858 init_imagemagick_functions,
7859 NULL
7862 /* Free X resources of imagemagick image IMG which is used on frame F. */
7864 static void
7865 imagemagick_clear_image (struct frame *f,
7866 struct image *img)
7868 x_clear_image (f, img);
7871 /* Return true if OBJECT is a valid IMAGEMAGICK image specification. Do
7872 this by calling parse_image_spec and supplying the keywords that
7873 identify the IMAGEMAGICK format. */
7875 static bool
7876 imagemagick_image_p (Lisp_Object object)
7878 struct image_keyword fmt[IMAGEMAGICK_LAST];
7879 memcpy (fmt, imagemagick_format, sizeof fmt);
7881 if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick))
7882 return 0;
7884 /* Must specify either the :data or :file keyword. */
7885 return fmt[IMAGEMAGICK_FILE].count + fmt[IMAGEMAGICK_DATA].count == 1;
7888 /* The GIF library also defines DrawRectangle, but its never used in Emacs.
7889 Therefore rename the function so it doesn't collide with ImageMagick. */
7890 #define DrawRectangle DrawRectangleGif
7891 #include <wand/MagickWand.h>
7893 /* ImageMagick 6.5.3 through 6.6.5 hid PixelGetMagickColor for some reason.
7894 Emacs seems to work fine with the hidden version, so unhide it. */
7895 #include <magick/version.h>
7896 #if 0x653 <= MagickLibVersion && MagickLibVersion <= 0x665
7897 extern WandExport void PixelGetMagickColor (const PixelWand *,
7898 MagickPixelPacket *);
7899 #endif
7901 /* Log ImageMagick error message.
7902 Useful when a ImageMagick function returns the status `MagickFalse'. */
7904 static void
7905 imagemagick_error (MagickWand *wand)
7907 char *description;
7908 ExceptionType severity;
7910 description = MagickGetException (wand, &severity);
7911 image_error ("ImageMagick error: %s",
7912 build_string (description),
7913 Qnil);
7914 MagickRelinquishMemory (description);
7917 /* Possibly give ImageMagick some extra help to determine the image
7918 type by supplying a "dummy" filename based on the Content-Type. */
7920 static char *
7921 imagemagick_filename_hint (Lisp_Object spec, char hint_buffer[MaxTextExtent])
7923 Lisp_Object symbol = intern ("image-format-suffixes");
7924 Lisp_Object val = find_symbol_value (symbol);
7925 Lisp_Object format;
7927 if (! CONSP (val))
7928 return NULL;
7930 format = image_spec_value (spec, intern (":format"), NULL);
7931 val = Fcar_safe (Fcdr_safe (Fassq (format, val)));
7932 if (! STRINGP (val))
7933 return NULL;
7935 /* It's OK to truncate the hint if it has MaxTextExtent or more bytes,
7936 as ImageMagick would ignore the extra bytes anyway. */
7937 snprintf (hint_buffer, MaxTextExtent, "/tmp/foo.%s", SSDATA (val));
7938 return hint_buffer;
7941 /* Animated images (e.g., GIF89a) are composed from one "master image"
7942 (which is the first one, and then there's a number of images that
7943 follow. If following images have non-transparent colors, these are
7944 composed "on top" of the master image. So, in general, one has to
7945 compute ann the preceding images to be able to display a particular
7946 sub-image.
7948 Computing all the preceding images is too slow, so we maintain a
7949 cache of previously computed images. We have to maintain a cache
7950 separate from the image cache, because the images may be scaled
7951 before display. */
7953 struct animation_cache
7955 MagickWand *wand;
7956 int index;
7957 struct timespec update_time;
7958 struct animation_cache *next;
7959 char signature[FLEXIBLE_ARRAY_MEMBER];
7962 static struct animation_cache *animation_cache = NULL;
7964 static struct animation_cache *
7965 imagemagick_create_cache (char *signature)
7967 struct animation_cache *cache
7968 = xmalloc (offsetof (struct animation_cache, signature)
7969 + strlen (signature) + 1);
7970 cache->wand = 0;
7971 cache->index = 0;
7972 cache->next = 0;
7973 strcpy (cache->signature, signature);
7974 return cache;
7977 /* Discard cached images that haven't been used for a minute. */
7978 static void
7979 imagemagick_prune_animation_cache (void)
7981 struct animation_cache **pcache = &animation_cache;
7982 struct timespec old = timespec_sub (current_timespec (),
7983 make_timespec (60, 0));
7985 while (*pcache)
7987 struct animation_cache *cache = *pcache;
7988 if (timespec_cmp (old, cache->update_time) <= 0)
7989 pcache = &cache->next;
7990 else
7992 if (cache->wand)
7993 DestroyMagickWand (cache->wand);
7994 *pcache = cache->next;
7995 xfree (cache);
8000 static struct animation_cache *
8001 imagemagick_get_animation_cache (MagickWand *wand)
8003 char *signature = MagickGetImageSignature (wand);
8004 struct animation_cache *cache;
8005 struct animation_cache **pcache = &animation_cache;
8007 imagemagick_prune_animation_cache ();
8009 while (1)
8011 cache = *pcache;
8012 if (! cache)
8014 *pcache = cache = imagemagick_create_cache (signature);
8015 break;
8017 if (strcmp (signature, cache->signature) == 0)
8018 break;
8019 pcache = &cache->next;
8022 DestroyString (signature);
8023 cache->update_time = current_timespec ();
8024 return cache;
8027 static MagickWand *
8028 imagemagick_compute_animated_image (MagickWand *super_wand, int ino)
8030 int i;
8031 MagickWand *composite_wand;
8032 size_t dest_width, dest_height;
8033 struct animation_cache *cache = imagemagick_get_animation_cache (super_wand);
8035 MagickSetIteratorIndex (super_wand, 0);
8037 if (ino == 0 || cache->wand == NULL || cache->index > ino)
8039 composite_wand = MagickGetImage (super_wand);
8040 if (cache->wand)
8041 DestroyMagickWand (cache->wand);
8043 else
8044 composite_wand = cache->wand;
8046 dest_height = MagickGetImageHeight (composite_wand);
8048 for (i = max (1, cache->index + 1); i <= ino; i++)
8050 MagickWand *sub_wand;
8051 PixelIterator *source_iterator, *dest_iterator;
8052 PixelWand **source, **dest;
8053 size_t source_width, source_height;
8054 ssize_t source_left, source_top;
8055 MagickPixelPacket pixel;
8056 DisposeType dispose;
8057 ptrdiff_t lines = 0;
8059 MagickSetIteratorIndex (super_wand, i);
8060 sub_wand = MagickGetImage (super_wand);
8062 MagickGetImagePage (sub_wand, &source_width, &source_height,
8063 &source_left, &source_top);
8065 /* This flag says how to handle transparent pixels. */
8066 dispose = MagickGetImageDispose (sub_wand);
8068 source_iterator = NewPixelIterator (sub_wand);
8069 if (! source_iterator)
8071 DestroyMagickWand (composite_wand);
8072 DestroyMagickWand (sub_wand);
8073 cache->wand = NULL;
8074 image_error ("Imagemagick pixel iterator creation failed",
8075 Qnil, Qnil);
8076 return NULL;
8079 dest_iterator = NewPixelIterator (composite_wand);
8080 if (! dest_iterator)
8082 DestroyMagickWand (composite_wand);
8083 DestroyMagickWand (sub_wand);
8084 DestroyPixelIterator (source_iterator);
8085 cache->wand = NULL;
8086 image_error ("Imagemagick pixel iterator creation failed",
8087 Qnil, Qnil);
8088 return NULL;
8091 /* The sub-image may not start at origin, so move the destination
8092 iterator to where the sub-image should start. */
8093 if (source_top > 0)
8095 PixelSetIteratorRow (dest_iterator, source_top);
8096 lines = source_top;
8099 while ((source = PixelGetNextIteratorRow (source_iterator, &source_width))
8100 != NULL)
8102 ptrdiff_t x;
8104 /* Sanity check. This shouldn't happen, but apparently
8105 does in some pictures. */
8106 if (++lines >= dest_height)
8107 break;
8109 dest = PixelGetNextIteratorRow (dest_iterator, &dest_width);
8110 for (x = 0; x < source_width; x++)
8112 /* Sanity check. This shouldn't happen, but apparently
8113 also does in some pictures. */
8114 if (x + source_left >= dest_width)
8115 break;
8116 /* Normally we only copy over non-transparent pixels,
8117 but if the disposal method is "Background", then we
8118 copy over all pixels. */
8119 if (dispose == BackgroundDispose || PixelGetAlpha (source[x]))
8121 PixelGetMagickColor (source[x], &pixel);
8122 PixelSetMagickColor (dest[x + source_left], &pixel);
8125 PixelSyncIterator (dest_iterator);
8128 DestroyPixelIterator (source_iterator);
8129 DestroyPixelIterator (dest_iterator);
8130 DestroyMagickWand (sub_wand);
8133 /* Cache a copy for the next iteration. The current wand will be
8134 destroyed by the caller. */
8135 cache->wand = CloneMagickWand (composite_wand);
8136 cache->index = ino;
8138 return composite_wand;
8142 /* Helper function for imagemagick_load, which does the actual loading
8143 given contents and size, apart from frame and image structures,
8144 passed from imagemagick_load. Uses librimagemagick to do most of
8145 the image processing.
8147 F is a pointer to the Emacs frame; IMG to the image structure to
8148 prepare; CONTENTS is the string containing the IMAGEMAGICK data to
8149 be parsed; SIZE is the number of bytes of data; and FILENAME is
8150 either the file name or the image data.
8152 Return true if successful. */
8154 static bool
8155 imagemagick_load_image (struct frame *f, struct image *img,
8156 unsigned char *contents, unsigned int size,
8157 char *filename)
8159 int width, height;
8160 size_t image_width, image_height;
8161 MagickBooleanType status;
8162 XImagePtr ximg;
8163 int x, y;
8164 MagickWand *image_wand;
8165 PixelIterator *iterator;
8166 PixelWand **pixels, *bg_wand = NULL;
8167 MagickPixelPacket pixel;
8168 Lisp_Object image;
8169 Lisp_Object value;
8170 Lisp_Object crop;
8171 EMACS_INT ino;
8172 int desired_width, desired_height;
8173 double rotation;
8174 int pixelwidth;
8175 char hint_buffer[MaxTextExtent];
8176 char *filename_hint = NULL;
8178 /* Handle image index for image types who can contain more than one image.
8179 Interface :index is same as for GIF. First we "ping" the image to see how
8180 many sub-images it contains. Pinging is faster than loading the image to
8181 find out things about it. */
8183 /* Initialize the imagemagick environment. */
8184 MagickWandGenesis ();
8185 image = image_spec_value (img->spec, QCindex, NULL);
8186 ino = INTEGERP (image) ? XFASTINT (image) : 0;
8187 image_wand = NewMagickWand ();
8189 if (filename)
8190 status = MagickReadImage (image_wand, filename);
8191 else
8193 filename_hint = imagemagick_filename_hint (img->spec, hint_buffer);
8194 MagickSetFilename (image_wand, filename_hint);
8195 status = MagickReadImageBlob (image_wand, contents, size);
8198 if (status == MagickFalse)
8200 imagemagick_error (image_wand);
8201 DestroyMagickWand (image_wand);
8202 return 0;
8205 if (ino < 0 || ino >= MagickGetNumberImages (image_wand))
8207 image_error ("Invalid image number `%s' in image `%s'",
8208 image, img->spec);
8209 DestroyMagickWand (image_wand);
8210 return 0;
8213 if (MagickGetImageDelay (image_wand) > 0)
8214 img->lisp_data =
8215 Fcons (Qdelay,
8216 Fcons (make_float (MagickGetImageDelay (image_wand) / 100.0),
8217 img->lisp_data));
8219 if (MagickGetNumberImages (image_wand) > 1)
8220 img->lisp_data =
8221 Fcons (Qcount,
8222 Fcons (make_number (MagickGetNumberImages (image_wand)),
8223 img->lisp_data));
8225 /* If we have an animated image, get the new wand based on the
8226 "super-wand". */
8227 if (MagickGetNumberImages (image_wand) > 1)
8229 MagickWand *super_wand = image_wand;
8230 image_wand = imagemagick_compute_animated_image (super_wand, ino);
8231 if (! image_wand)
8232 image_wand = super_wand;
8233 else
8234 DestroyMagickWand (super_wand);
8237 /* Retrieve the frame's background color, for use later. */
8239 XColor bgcolor;
8240 Lisp_Object specified_bg;
8242 specified_bg = image_spec_value (img->spec, QCbackground, NULL);
8243 if (!STRINGP (specified_bg)
8244 || !x_defined_color (f, SSDATA (specified_bg), &bgcolor, 0))
8245 x_query_frame_background_color (f, &bgcolor);
8247 bg_wand = NewPixelWand ();
8248 PixelSetRed (bg_wand, (double) bgcolor.red / 65535);
8249 PixelSetGreen (bg_wand, (double) bgcolor.green / 65535);
8250 PixelSetBlue (bg_wand, (double) bgcolor.blue / 65535);
8253 compute_image_size (MagickGetImageWidth (image_wand),
8254 MagickGetImageHeight (image_wand),
8255 img->spec, &desired_width, &desired_height);
8257 if (desired_width != -1 && desired_height != -1)
8259 status = MagickScaleImage (image_wand, desired_width, desired_height);
8260 if (status == MagickFalse)
8262 image_error ("Imagemagick scale failed", Qnil, Qnil);
8263 imagemagick_error (image_wand);
8264 goto imagemagick_error;
8268 /* crop behaves similar to image slicing in Emacs but is more memory
8269 efficient. */
8270 crop = image_spec_value (img->spec, QCcrop, NULL);
8272 if (CONSP (crop) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop)))
8274 /* After some testing, it seems MagickCropImage is the fastest crop
8275 function in ImageMagick. This crop function seems to do less copying
8276 than the alternatives, but it still reads the entire image into memory
8277 before cropping, which is apparently difficult to avoid when using
8278 imagemagick. */
8279 size_t crop_width = XINT (XCAR (crop));
8280 crop = XCDR (crop);
8281 if (CONSP (crop) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop)))
8283 size_t crop_height = XINT (XCAR (crop));
8284 crop = XCDR (crop);
8285 if (CONSP (crop) && TYPE_RANGED_INTEGERP (ssize_t, XCAR (crop)))
8287 ssize_t crop_x = XINT (XCAR (crop));
8288 crop = XCDR (crop);
8289 if (CONSP (crop) && TYPE_RANGED_INTEGERP (ssize_t, XCAR (crop)))
8291 ssize_t crop_y = XINT (XCAR (crop));
8292 MagickCropImage (image_wand, crop_width, crop_height,
8293 crop_x, crop_y);
8299 /* Furthermore :rotation. we need background color and angle for
8300 rotation. */
8302 TODO background handling for rotation specified_bg =
8303 image_spec_value (img->spec, QCbackground, NULL); if (!STRINGP
8304 (specified_bg). */
8305 value = image_spec_value (img->spec, QCrotation, NULL);
8306 if (FLOATP (value))
8308 rotation = extract_float (value);
8309 status = MagickRotateImage (image_wand, bg_wand, rotation);
8310 if (status == MagickFalse)
8312 image_error ("Imagemagick image rotate failed", Qnil, Qnil);
8313 imagemagick_error (image_wand);
8314 goto imagemagick_error;
8318 /* Set the canvas background color to the frame or specified
8319 background, and flatten the image. Note: as of ImageMagick
8320 6.6.0, SVG image transparency is not handled properly
8321 (e.g. etc/images/splash.svg shows a white background always). */
8323 MagickWand *new_wand;
8324 MagickSetImageBackgroundColor (image_wand, bg_wand);
8325 #ifdef HAVE_MAGICKMERGEIMAGELAYERS
8326 new_wand = MagickMergeImageLayers (image_wand, MergeLayer);
8327 #else
8328 new_wand = MagickFlattenImages (image_wand);
8329 #endif
8330 DestroyMagickWand (image_wand);
8331 image_wand = new_wand;
8334 /* Finally we are done manipulating the image. Figure out the
8335 resulting width/height and transfer ownership to Emacs. */
8336 image_height = MagickGetImageHeight (image_wand);
8337 image_width = MagickGetImageWidth (image_wand);
8339 if (! (image_width <= INT_MAX && image_height <= INT_MAX
8340 && check_image_size (f, image_width, image_height)))
8342 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
8343 goto imagemagick_error;
8346 width = image_width;
8347 height = image_height;
8349 /* We can now get a valid pixel buffer from the imagemagick file, if all
8350 went ok. */
8352 init_color_table ();
8354 #if defined (HAVE_MAGICKEXPORTIMAGEPIXELS) && ! defined (HAVE_NS)
8355 if (imagemagick_render_type != 0)
8357 /* Magicexportimage is normally faster than pixelpushing. This
8358 method is also well tested. Some aspects of this method are
8359 ad-hoc and needs to be more researched. */
8360 int imagedepth = 24; /*MagickGetImageDepth(image_wand);*/
8361 const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP"; /*"RGBP";*/
8362 /* Try to create a x pixmap to hold the imagemagick pixmap. */
8363 if (!image_create_x_image_and_pixmap (f, img, width, height, imagedepth,
8364 &ximg, 0))
8366 #ifdef COLOR_TABLE_SUPPORT
8367 free_color_table ();
8368 #endif
8369 image_error ("Imagemagick X bitmap allocation failure", Qnil, Qnil);
8370 goto imagemagick_error;
8373 /* Oddly, the below code doesn't seem to work:*/
8374 /* switch(ximg->bitmap_unit){ */
8375 /* case 8: */
8376 /* pixelwidth=CharPixel; */
8377 /* break; */
8378 /* case 16: */
8379 /* pixelwidth=ShortPixel; */
8380 /* break; */
8381 /* case 32: */
8382 /* pixelwidth=LongPixel; */
8383 /* break; */
8384 /* } */
8386 Here im just guessing the format of the bitmap.
8387 happens to work fine for:
8388 - bw djvu images
8389 on rgb display.
8390 seems about 3 times as fast as pixel pushing(not carefully measured)
8392 pixelwidth = CharPixel; /*??? TODO figure out*/
8393 MagickExportImagePixels (image_wand, 0, 0, width, height,
8394 exportdepth, pixelwidth, ximg->data);
8396 else
8397 #endif /* HAVE_MAGICKEXPORTIMAGEPIXELS */
8399 size_t image_height;
8400 MagickRealType color_scale = 65535.0 / QuantumRange;
8402 /* Try to create a x pixmap to hold the imagemagick pixmap. */
8403 if (!image_create_x_image_and_pixmap (f, img, width, height, 0,
8404 &ximg, 0))
8406 #ifdef COLOR_TABLE_SUPPORT
8407 free_color_table ();
8408 #endif
8409 image_error ("Imagemagick X bitmap allocation failure", Qnil, Qnil);
8410 goto imagemagick_error;
8413 /* Copy imagemagick image to x with primitive yet robust pixel
8414 pusher loop. This has been tested a lot with many different
8415 images. */
8417 /* Copy pixels from the imagemagick image structure to the x image map. */
8418 iterator = NewPixelIterator (image_wand);
8419 if (! iterator)
8421 #ifdef COLOR_TABLE_SUPPORT
8422 free_color_table ();
8423 #endif
8424 x_destroy_x_image (ximg);
8425 image_error ("Imagemagick pixel iterator creation failed",
8426 Qnil, Qnil);
8427 goto imagemagick_error;
8430 image_height = MagickGetImageHeight (image_wand);
8431 for (y = 0; y < image_height; y++)
8433 size_t row_width;
8434 pixels = PixelGetNextIteratorRow (iterator, &row_width);
8435 if (! pixels)
8436 break;
8437 int xlim = min (row_width, width);
8438 for (x = 0; x < xlim; x++)
8440 PixelGetMagickColor (pixels[x], &pixel);
8441 XPutPixel (ximg, x, y,
8442 lookup_rgb_color (f,
8443 color_scale * pixel.red,
8444 color_scale * pixel.green,
8445 color_scale * pixel.blue));
8448 DestroyPixelIterator (iterator);
8451 #ifdef COLOR_TABLE_SUPPORT
8452 /* Remember colors allocated for this image. */
8453 img->colors = colors_in_color_table (&img->ncolors);
8454 free_color_table ();
8455 #endif /* COLOR_TABLE_SUPPORT */
8457 img->width = width;
8458 img->height = height;
8460 /* Put ximg into the image. */
8461 image_put_x_image (f, img, ximg, 0);
8463 /* Final cleanup. image_wand should be the only resource left. */
8464 DestroyMagickWand (image_wand);
8465 if (bg_wand) DestroyPixelWand (bg_wand);
8467 /* `MagickWandTerminus' terminates the imagemagick environment. */
8468 MagickWandTerminus ();
8470 return 1;
8472 imagemagick_error:
8473 DestroyMagickWand (image_wand);
8474 if (bg_wand) DestroyPixelWand (bg_wand);
8476 MagickWandTerminus ();
8477 /* TODO more cleanup. */
8478 image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil);
8479 return 0;
8483 /* Load IMAGEMAGICK image IMG for use on frame F. Value is true if
8484 successful. this function will go into the imagemagick_type structure, and
8485 the prototype thus needs to be compatible with that structure. */
8487 static bool
8488 imagemagick_load (struct frame *f, struct image *img)
8490 bool success_p = 0;
8491 Lisp_Object file_name;
8493 /* If IMG->spec specifies a file name, create a non-file spec from it. */
8494 file_name = image_spec_value (img->spec, QCfile, NULL);
8495 if (STRINGP (file_name))
8497 Lisp_Object file;
8499 file = x_find_image_file (file_name);
8500 if (!STRINGP (file))
8502 image_error ("Cannot find image file `%s'", file_name, Qnil);
8503 return 0;
8505 #ifdef WINDOWSNT
8506 file = ansi_encode_filename (file);
8507 #endif
8508 success_p = imagemagick_load_image (f, img, 0, 0, SSDATA (file));
8510 /* Else its not a file, its a lisp object. Load the image from a
8511 lisp object rather than a file. */
8512 else
8514 Lisp_Object data;
8516 data = image_spec_value (img->spec, QCdata, NULL);
8517 if (!STRINGP (data))
8519 image_error ("Invalid image data `%s'", data, Qnil);
8520 return 0;
8522 success_p = imagemagick_load_image (f, img, SDATA (data),
8523 SBYTES (data), NULL);
8526 return success_p;
8529 DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
8530 doc: /* Return a list of image types supported by ImageMagick.
8531 Each entry in this list is a symbol named after an ImageMagick format
8532 tag. See the ImageMagick manual for a list of ImageMagick formats and
8533 their descriptions (http://www.imagemagick.org/script/formats.php).
8534 You can also try the shell command: `identify -list format'.
8536 Note that ImageMagick recognizes many file-types that Emacs does not
8537 recognize as images, such as C. See `imagemagick-types-enable'
8538 and `imagemagick-types-inhibit'. */)
8539 (void)
8541 Lisp_Object typelist = Qnil;
8542 size_t numf = 0;
8543 ExceptionInfo ex;
8544 char **imtypes;
8545 size_t i;
8547 GetExceptionInfo(&ex);
8548 imtypes = GetMagickList ("*", &numf, &ex);
8549 DestroyExceptionInfo(&ex);
8551 for (i = 0; i < numf; i++)
8553 Lisp_Object imagemagicktype = intern (imtypes[i]);
8554 typelist = Fcons (imagemagicktype, typelist);
8555 imtypes[i] = MagickRelinquishMemory (imtypes[i]);
8558 MagickRelinquishMemory (imtypes);
8559 return Fnreverse (typelist);
8562 #endif /* defined (HAVE_IMAGEMAGICK) */
8566 /***********************************************************************
8568 ***********************************************************************/
8570 #ifdef HAVE_RSVG
8572 /* Function prototypes. */
8574 static bool svg_image_p (Lisp_Object object);
8575 static bool svg_load (struct frame *f, struct image *img);
8577 static bool svg_load_image (struct frame *, struct image *,
8578 unsigned char *, ptrdiff_t, char *);
8580 /* Indices of image specification fields in svg_format, below. */
8582 enum svg_keyword_index
8584 SVG_TYPE,
8585 SVG_DATA,
8586 SVG_FILE,
8587 SVG_ASCENT,
8588 SVG_MARGIN,
8589 SVG_RELIEF,
8590 SVG_ALGORITHM,
8591 SVG_HEURISTIC_MASK,
8592 SVG_MASK,
8593 SVG_BACKGROUND,
8594 SVG_LAST
8597 /* Vector of image_keyword structures describing the format
8598 of valid user-defined image specifications. */
8600 static const struct image_keyword svg_format[SVG_LAST] =
8602 {":type", IMAGE_SYMBOL_VALUE, 1},
8603 {":data", IMAGE_STRING_VALUE, 0},
8604 {":file", IMAGE_STRING_VALUE, 0},
8605 {":ascent", IMAGE_ASCENT_VALUE, 0},
8606 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
8607 {":relief", IMAGE_INTEGER_VALUE, 0},
8608 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8609 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8610 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8611 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
8614 # if defined HAVE_NTGUI && defined WINDOWSNT
8615 static bool init_svg_functions (void);
8616 # else
8617 #define init_svg_functions NULL
8618 # endif
8620 /* Structure describing the image type `svg'. Its the same type of
8621 structure defined for all image formats, handled by emacs image
8622 functions. See struct image_type in dispextern.h. */
8624 static struct image_type svg_type =
8626 XSYMBOL_INIT (Qsvg),
8627 svg_image_p,
8628 svg_load,
8629 x_clear_image,
8630 init_svg_functions,
8631 NULL
8635 /* Return true if OBJECT is a valid SVG image specification. Do
8636 this by calling parse_image_spec and supplying the keywords that
8637 identify the SVG format. */
8639 static bool
8640 svg_image_p (Lisp_Object object)
8642 struct image_keyword fmt[SVG_LAST];
8643 memcpy (fmt, svg_format, sizeof fmt);
8645 if (!parse_image_spec (object, fmt, SVG_LAST, Qsvg))
8646 return 0;
8648 /* Must specify either the :data or :file keyword. */
8649 return fmt[SVG_FILE].count + fmt[SVG_DATA].count == 1;
8652 # include <librsvg/rsvg.h>
8654 # ifdef WINDOWSNT
8656 /* SVG library functions. */
8657 DEF_DLL_FN (RsvgHandle *, rsvg_handle_new, (void));
8658 DEF_DLL_FN (void, rsvg_handle_get_dimensions,
8659 (RsvgHandle *, RsvgDimensionData *));
8660 DEF_DLL_FN (gboolean, rsvg_handle_write,
8661 (RsvgHandle *, const guchar *, gsize, GError **));
8662 DEF_DLL_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **));
8663 DEF_DLL_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *));
8664 DEF_DLL_FN (void, rsvg_handle_set_base_uri, (RsvgHandle *, const char *));
8666 DEF_DLL_FN (int, gdk_pixbuf_get_width, (const GdkPixbuf *));
8667 DEF_DLL_FN (int, gdk_pixbuf_get_height, (const GdkPixbuf *));
8668 DEF_DLL_FN (guchar *, gdk_pixbuf_get_pixels, (const GdkPixbuf *));
8669 DEF_DLL_FN (int, gdk_pixbuf_get_rowstride, (const GdkPixbuf *));
8670 DEF_DLL_FN (GdkColorspace, gdk_pixbuf_get_colorspace, (const GdkPixbuf *));
8671 DEF_DLL_FN (int, gdk_pixbuf_get_n_channels, (const GdkPixbuf *));
8672 DEF_DLL_FN (gboolean, gdk_pixbuf_get_has_alpha, (const GdkPixbuf *));
8673 DEF_DLL_FN (int, gdk_pixbuf_get_bits_per_sample, (const GdkPixbuf *));
8675 # if ! GLIB_CHECK_VERSION (2, 36, 0)
8676 DEF_DLL_FN (void, g_type_init, (void));
8677 # endif
8678 DEF_DLL_FN (void, g_object_unref, (gpointer));
8679 DEF_DLL_FN (void, g_error_free, (GError *));
8681 static bool
8682 init_svg_functions (void)
8684 HMODULE library, gdklib = NULL, glib = NULL, gobject = NULL;
8686 if (!(glib = w32_delayed_load (Qglib))
8687 || !(gobject = w32_delayed_load (Qgobject))
8688 || !(gdklib = w32_delayed_load (Qgdk_pixbuf))
8689 || !(library = w32_delayed_load (Qsvg)))
8691 if (gdklib) FreeLibrary (gdklib);
8692 if (gobject) FreeLibrary (gobject);
8693 if (glib) FreeLibrary (glib);
8694 return 0;
8697 LOAD_DLL_FN (library, rsvg_handle_new);
8698 LOAD_DLL_FN (library, rsvg_handle_get_dimensions);
8699 LOAD_DLL_FN (library, rsvg_handle_write);
8700 LOAD_DLL_FN (library, rsvg_handle_close);
8701 LOAD_DLL_FN (library, rsvg_handle_get_pixbuf);
8702 LOAD_DLL_FN (library, rsvg_handle_set_base_uri);
8704 LOAD_DLL_FN (gdklib, gdk_pixbuf_get_width);
8705 LOAD_DLL_FN (gdklib, gdk_pixbuf_get_height);
8706 LOAD_DLL_FN (gdklib, gdk_pixbuf_get_pixels);
8707 LOAD_DLL_FN (gdklib, gdk_pixbuf_get_rowstride);
8708 LOAD_DLL_FN (gdklib, gdk_pixbuf_get_colorspace);
8709 LOAD_DLL_FN (gdklib, gdk_pixbuf_get_n_channels);
8710 LOAD_DLL_FN (gdklib, gdk_pixbuf_get_has_alpha);
8711 LOAD_DLL_FN (gdklib, gdk_pixbuf_get_bits_per_sample);
8713 # if ! GLIB_CHECK_VERSION (2, 36, 0)
8714 LOAD_DLL_FN (gobject, g_type_init);
8715 # endif
8716 LOAD_DLL_FN (gobject, g_object_unref);
8717 LOAD_DLL_FN (glib, g_error_free);
8719 return 1;
8722 /* The following aliases for library functions allow dynamic loading
8723 to be used on some platforms. */
8725 # undef gdk_pixbuf_get_bits_per_sample
8726 # undef gdk_pixbuf_get_colorspace
8727 # undef gdk_pixbuf_get_has_alpha
8728 # undef gdk_pixbuf_get_height
8729 # undef gdk_pixbuf_get_n_channels
8730 # undef gdk_pixbuf_get_pixels
8731 # undef gdk_pixbuf_get_rowstride
8732 # undef gdk_pixbuf_get_width
8733 # undef g_error_free
8734 # undef g_object_unref
8735 # undef g_type_init
8736 # undef rsvg_handle_close
8737 # undef rsvg_handle_get_dimensions
8738 # undef rsvg_handle_get_pixbuf
8739 # undef rsvg_handle_new
8740 # undef rsvg_handle_set_base_uri
8741 # undef rsvg_handle_write
8743 # define gdk_pixbuf_get_bits_per_sample fn_gdk_pixbuf_get_bits_per_sample
8744 # define gdk_pixbuf_get_colorspace fn_gdk_pixbuf_get_colorspace
8745 # define gdk_pixbuf_get_has_alpha fn_gdk_pixbuf_get_has_alpha
8746 # define gdk_pixbuf_get_height fn_gdk_pixbuf_get_height
8747 # define gdk_pixbuf_get_n_channels fn_gdk_pixbuf_get_n_channels
8748 # define gdk_pixbuf_get_pixels fn_gdk_pixbuf_get_pixels
8749 # define gdk_pixbuf_get_rowstride fn_gdk_pixbuf_get_rowstride
8750 # define gdk_pixbuf_get_width fn_gdk_pixbuf_get_width
8751 # define g_error_free fn_g_error_free
8752 # define g_object_unref fn_g_object_unref
8753 # define g_type_init fn_g_type_init
8754 # define rsvg_handle_close fn_rsvg_handle_close
8755 # define rsvg_handle_get_dimensions fn_rsvg_handle_get_dimensions
8756 # define rsvg_handle_get_pixbuf fn_rsvg_handle_get_pixbuf
8757 # define rsvg_handle_new fn_rsvg_handle_new
8758 # define rsvg_handle_set_base_uri fn_rsvg_handle_set_base_uri
8759 # define rsvg_handle_write fn_rsvg_handle_write
8761 # endif /* !WINDOWSNT */
8763 /* Load SVG image IMG for use on frame F. Value is true if
8764 successful. */
8766 static bool
8767 svg_load (struct frame *f, struct image *img)
8769 bool success_p = 0;
8770 Lisp_Object file_name;
8772 /* If IMG->spec specifies a file name, create a non-file spec from it. */
8773 file_name = image_spec_value (img->spec, QCfile, NULL);
8774 if (STRINGP (file_name))
8776 Lisp_Object file;
8777 unsigned char *contents;
8778 ptrdiff_t size;
8780 file = x_find_image_file (file_name);
8781 if (!STRINGP (file))
8783 image_error ("Cannot find image file `%s'", file_name, Qnil);
8784 return 0;
8787 /* Read the entire file into memory. */
8788 contents = slurp_file (SSDATA (file), &size);
8789 if (contents == NULL)
8791 image_error ("Error loading SVG image `%s'", img->spec, Qnil);
8792 return 0;
8794 /* If the file was slurped into memory properly, parse it. */
8795 success_p = svg_load_image (f, img, contents, size, SSDATA (file));
8796 xfree (contents);
8798 /* Else its not a file, its a lisp object. Load the image from a
8799 lisp object rather than a file. */
8800 else
8802 Lisp_Object data, original_filename;
8804 data = image_spec_value (img->spec, QCdata, NULL);
8805 if (!STRINGP (data))
8807 image_error ("Invalid image data `%s'", data, Qnil);
8808 return 0;
8810 original_filename = BVAR (current_buffer, filename);
8811 success_p = svg_load_image (f, img, SDATA (data), SBYTES (data),
8812 (NILP (original_filename) ? NULL
8813 : SSDATA (original_filename)));
8816 return success_p;
8819 /* svg_load_image is a helper function for svg_load, which does the
8820 actual loading given contents and size, apart from frame and image
8821 structures, passed from svg_load.
8823 Uses librsvg to do most of the image processing.
8825 Returns true when successful. */
8826 static bool
8827 svg_load_image (struct frame *f, /* Pointer to emacs frame structure. */
8828 struct image *img, /* Pointer to emacs image structure. */
8829 unsigned char *contents, /* String containing the SVG XML data to be parsed. */
8830 ptrdiff_t size, /* Size of data in bytes. */
8831 char *filename) /* Name of SVG file being loaded. */
8833 RsvgHandle *rsvg_handle;
8834 RsvgDimensionData dimension_data;
8835 GError *err = NULL;
8836 GdkPixbuf *pixbuf;
8837 int width;
8838 int height;
8839 const guint8 *pixels;
8840 int rowstride;
8841 XImagePtr ximg;
8842 Lisp_Object specified_bg;
8843 XColor background;
8844 int x;
8845 int y;
8847 #if ! GLIB_CHECK_VERSION (2, 36, 0)
8848 /* g_type_init is a glib function that must be called prior to
8849 using gnome type library functions (obsolete since 2.36.0). */
8850 g_type_init ();
8851 #endif
8853 /* Make a handle to a new rsvg object. */
8854 rsvg_handle = rsvg_handle_new ();
8856 /* Set base_uri for properly handling referenced images (via 'href').
8857 See rsvg bug 596114 - "image refs are relative to curdir, not .svg file"
8858 (https://bugzilla.gnome.org/show_bug.cgi?id=596114). */
8859 if (filename)
8860 rsvg_handle_set_base_uri(rsvg_handle, filename);
8862 /* Parse the contents argument and fill in the rsvg_handle. */
8863 rsvg_handle_write (rsvg_handle, contents, size, &err);
8864 if (err) goto rsvg_error;
8866 /* The parsing is complete, rsvg_handle is ready to used, close it
8867 for further writes. */
8868 rsvg_handle_close (rsvg_handle, &err);
8869 if (err) goto rsvg_error;
8871 rsvg_handle_get_dimensions (rsvg_handle, &dimension_data);
8872 if (! check_image_size (f, dimension_data.width, dimension_data.height))
8874 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
8875 goto rsvg_error;
8878 /* We can now get a valid pixel buffer from the svg file, if all
8879 went ok. */
8880 pixbuf = rsvg_handle_get_pixbuf (rsvg_handle);
8881 if (!pixbuf) goto rsvg_error;
8882 g_object_unref (rsvg_handle);
8884 /* Extract some meta data from the svg handle. */
8885 width = gdk_pixbuf_get_width (pixbuf);
8886 height = gdk_pixbuf_get_height (pixbuf);
8887 pixels = gdk_pixbuf_get_pixels (pixbuf);
8888 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
8890 /* Validate the svg meta data. */
8891 eassert (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB);
8892 eassert (gdk_pixbuf_get_n_channels (pixbuf) == 4);
8893 eassert (gdk_pixbuf_get_has_alpha (pixbuf));
8894 eassert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
8896 /* Try to create a x pixmap to hold the svg pixmap. */
8897 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
8899 g_object_unref (pixbuf);
8900 return 0;
8903 init_color_table ();
8905 /* Handle alpha channel by combining the image with a background
8906 color. */
8907 specified_bg = image_spec_value (img->spec, QCbackground, NULL);
8908 if (!STRINGP (specified_bg)
8909 || !x_defined_color (f, SSDATA (specified_bg), &background, 0))
8910 x_query_frame_background_color (f, &background);
8912 /* SVG pixmaps specify transparency in the last byte, so right
8913 shift 8 bits to get rid of it, since emacs doesn't support
8914 transparency. */
8915 background.red >>= 8;
8916 background.green >>= 8;
8917 background.blue >>= 8;
8919 /* This loop handles opacity values, since Emacs assumes
8920 non-transparent images. Each pixel must be "flattened" by
8921 calculating the resulting color, given the transparency of the
8922 pixel, and the image background color. */
8923 for (y = 0; y < height; ++y)
8925 for (x = 0; x < width; ++x)
8927 int red;
8928 int green;
8929 int blue;
8930 int opacity;
8932 red = *pixels++;
8933 green = *pixels++;
8934 blue = *pixels++;
8935 opacity = *pixels++;
8937 red = ((red * opacity)
8938 + (background.red * ((1 << 8) - opacity)));
8939 green = ((green * opacity)
8940 + (background.green * ((1 << 8) - opacity)));
8941 blue = ((blue * opacity)
8942 + (background.blue * ((1 << 8) - opacity)));
8944 XPutPixel (ximg, x, y, lookup_rgb_color (f, red, green, blue));
8947 pixels += rowstride - 4 * width;
8950 #ifdef COLOR_TABLE_SUPPORT
8951 /* Remember colors allocated for this image. */
8952 img->colors = colors_in_color_table (&img->ncolors);
8953 free_color_table ();
8954 #endif /* COLOR_TABLE_SUPPORT */
8956 g_object_unref (pixbuf);
8958 img->width = width;
8959 img->height = height;
8961 /* Maybe fill in the background field while we have ximg handy.
8962 Casting avoids a GCC warning. */
8963 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
8965 /* Put ximg into the image. */
8966 image_put_x_image (f, img, ximg, 0);
8968 return 1;
8970 rsvg_error:
8971 g_object_unref (rsvg_handle);
8972 /* FIXME: Use error->message so the user knows what is the actual
8973 problem with the image. */
8974 image_error ("Error parsing SVG image `%s'", img->spec, Qnil);
8975 g_error_free (err);
8976 return 0;
8979 #endif /* defined (HAVE_RSVG) */
8984 /***********************************************************************
8985 Ghostscript
8986 ***********************************************************************/
8988 #ifdef HAVE_X_WINDOWS
8989 #define HAVE_GHOSTSCRIPT 1
8990 #endif /* HAVE_X_WINDOWS */
8992 #ifdef HAVE_GHOSTSCRIPT
8994 static bool gs_image_p (Lisp_Object object);
8995 static bool gs_load (struct frame *f, struct image *img);
8996 static void gs_clear_image (struct frame *f, struct image *img);
8998 /* Indices of image specification fields in gs_format, below. */
9000 enum gs_keyword_index
9002 GS_TYPE,
9003 GS_PT_WIDTH,
9004 GS_PT_HEIGHT,
9005 GS_FILE,
9006 GS_LOADER,
9007 GS_BOUNDING_BOX,
9008 GS_ASCENT,
9009 GS_MARGIN,
9010 GS_RELIEF,
9011 GS_ALGORITHM,
9012 GS_HEURISTIC_MASK,
9013 GS_MASK,
9014 GS_BACKGROUND,
9015 GS_LAST
9018 /* Vector of image_keyword structures describing the format
9019 of valid user-defined image specifications. */
9021 static const struct image_keyword gs_format[GS_LAST] =
9023 {":type", IMAGE_SYMBOL_VALUE, 1},
9024 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE, 1},
9025 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE, 1},
9026 {":file", IMAGE_STRING_VALUE, 1},
9027 {":loader", IMAGE_FUNCTION_VALUE, 0},
9028 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1},
9029 {":ascent", IMAGE_ASCENT_VALUE, 0},
9030 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
9031 {":relief", IMAGE_INTEGER_VALUE, 0},
9032 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
9033 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
9034 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
9035 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
9038 /* Structure describing the image type `ghostscript'. */
9040 static struct image_type gs_type =
9042 XSYMBOL_INIT (Qpostscript),
9043 gs_image_p,
9044 gs_load,
9045 gs_clear_image,
9046 NULL,
9047 NULL
9051 /* Free X resources of Ghostscript image IMG which is used on frame F. */
9053 static void
9054 gs_clear_image (struct frame *f, struct image *img)
9056 x_clear_image (f, img);
9060 /* Return true if OBJECT is a valid Ghostscript image
9061 specification. */
9063 static bool
9064 gs_image_p (Lisp_Object object)
9066 struct image_keyword fmt[GS_LAST];
9067 Lisp_Object tem;
9068 int i;
9070 memcpy (fmt, gs_format, sizeof fmt);
9072 if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript))
9073 return 0;
9075 /* Bounding box must be a list or vector containing 4 integers. */
9076 tem = fmt[GS_BOUNDING_BOX].value;
9077 if (CONSP (tem))
9079 for (i = 0; i < 4; ++i, tem = XCDR (tem))
9080 if (!CONSP (tem) || !INTEGERP (XCAR (tem)))
9081 return 0;
9082 if (!NILP (tem))
9083 return 0;
9085 else if (VECTORP (tem))
9087 if (ASIZE (tem) != 4)
9088 return 0;
9089 for (i = 0; i < 4; ++i)
9090 if (!INTEGERP (AREF (tem, i)))
9091 return 0;
9093 else
9094 return 0;
9096 return 1;
9100 /* Load Ghostscript image IMG for use on frame F. Value is true
9101 if successful. */
9103 static bool
9104 gs_load (struct frame *f, struct image *img)
9106 uprintmax_t printnum1, printnum2;
9107 char buffer[sizeof " " + INT_STRLEN_BOUND (printmax_t)];
9108 Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width;
9109 Lisp_Object frame;
9110 double in_width, in_height;
9111 Lisp_Object pixel_colors = Qnil;
9113 /* Compute pixel size of pixmap needed from the given size in the
9114 image specification. Sizes in the specification are in pt. 1 pt
9115 = 1/72 in, xdpi and ydpi are stored in the frame's X display
9116 info. */
9117 pt_width = image_spec_value (img->spec, QCpt_width, NULL);
9118 in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0;
9119 in_width *= FRAME_RES_X (f);
9120 pt_height = image_spec_value (img->spec, QCpt_height, NULL);
9121 in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0;
9122 in_height *= FRAME_RES_Y (f);
9124 if (! (in_width <= INT_MAX && in_height <= INT_MAX
9125 && check_image_size (f, in_width, in_height)))
9127 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
9128 return 0;
9130 img->width = in_width;
9131 img->height = in_height;
9133 /* Create the pixmap. */
9134 eassert (img->pixmap == NO_PIXMAP);
9136 if (x_check_image_size (0, img->width, img->height))
9138 /* Only W32 version did BLOCK_INPUT here. ++kfs */
9139 block_input ();
9140 img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
9141 img->width, img->height,
9142 DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
9143 unblock_input ();
9146 if (!img->pixmap)
9148 image_error ("Unable to create pixmap for `%s'", img->spec, Qnil);
9149 return 0;
9152 /* Call the loader to fill the pixmap. It returns a process object
9153 if successful. We do not record_unwind_protect here because
9154 other places in redisplay like calling window scroll functions
9155 don't either. Let the Lisp loader use `unwind-protect' instead. */
9156 printnum1 = FRAME_X_WINDOW (f);
9157 printnum2 = img->pixmap;
9158 window_and_pixmap_id
9159 = make_formatted_string (buffer, "%"pMu" %"pMu, printnum1, printnum2);
9161 printnum1 = FRAME_FOREGROUND_PIXEL (f);
9162 printnum2 = FRAME_BACKGROUND_PIXEL (f);
9163 pixel_colors
9164 = make_formatted_string (buffer, "%"pMu" %"pMu, printnum1, printnum2);
9166 XSETFRAME (frame, f);
9167 loader = image_spec_value (img->spec, QCloader, NULL);
9168 if (NILP (loader))
9169 loader = intern ("gs-load-image");
9171 img->lisp_data = call6 (loader, frame, img->spec,
9172 make_number (img->width),
9173 make_number (img->height),
9174 window_and_pixmap_id,
9175 pixel_colors);
9176 return PROCESSP (img->lisp_data);
9180 /* Kill the Ghostscript process that was started to fill PIXMAP on
9181 frame F. Called from XTread_socket when receiving an event
9182 telling Emacs that Ghostscript has finished drawing. */
9184 void
9185 x_kill_gs_process (Pixmap pixmap, struct frame *f)
9187 struct image_cache *c = FRAME_IMAGE_CACHE (f);
9188 int class;
9189 ptrdiff_t i;
9190 struct image *img;
9192 /* Find the image containing PIXMAP. */
9193 for (i = 0; i < c->used; ++i)
9194 if (c->images[i]->pixmap == pixmap)
9195 break;
9197 /* Should someone in between have cleared the image cache, for
9198 instance, give up. */
9199 if (i == c->used)
9200 return;
9202 /* Kill the GS process. We should have found PIXMAP in the image
9203 cache and its image should contain a process object. */
9204 img = c->images[i];
9205 eassert (PROCESSP (img->lisp_data));
9206 Fkill_process (img->lisp_data, Qnil);
9207 img->lisp_data = Qnil;
9209 #if defined (HAVE_X_WINDOWS)
9211 /* On displays with a mutable colormap, figure out the colors
9212 allocated for the image by looking at the pixels of an XImage for
9213 img->pixmap. */
9214 class = FRAME_X_VISUAL (f)->class;
9215 if (class != StaticColor && class != StaticGray && class != TrueColor)
9217 XImagePtr ximg;
9219 block_input ();
9221 /* Try to get an XImage for img->pixmep. */
9222 ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
9223 0, 0, img->width, img->height, ~0, ZPixmap);
9224 if (ximg)
9226 int x, y;
9228 /* Initialize the color table. */
9229 init_color_table ();
9231 /* For each pixel of the image, look its color up in the
9232 color table. After having done so, the color table will
9233 contain an entry for each color used by the image. */
9234 for (y = 0; y < img->height; ++y)
9235 for (x = 0; x < img->width; ++x)
9237 unsigned long pixel = XGetPixel (ximg, x, y);
9238 lookup_pixel_color (f, pixel);
9241 /* Record colors in the image. Free color table and XImage. */
9242 #ifdef COLOR_TABLE_SUPPORT
9243 img->colors = colors_in_color_table (&img->ncolors);
9244 free_color_table ();
9245 #endif
9246 XDestroyImage (ximg);
9248 #if 0 /* This doesn't seem to be the case. If we free the colors
9249 here, we get a BadAccess later in x_clear_image when
9250 freeing the colors. */
9251 /* We have allocated colors once, but Ghostscript has also
9252 allocated colors on behalf of us. So, to get the
9253 reference counts right, free them once. */
9254 if (img->ncolors)
9255 x_free_colors (f, img->colors, img->ncolors);
9256 #endif
9258 else
9259 image_error ("Cannot get X image of `%s'; colors will not be freed",
9260 img->spec, Qnil);
9262 unblock_input ();
9264 #endif /* HAVE_X_WINDOWS */
9266 /* Now that we have the pixmap, compute mask and transform the
9267 image if requested. */
9268 block_input ();
9269 postprocess_image (f, img);
9270 unblock_input ();
9273 #endif /* HAVE_GHOSTSCRIPT */
9276 /***********************************************************************
9277 Tests
9278 ***********************************************************************/
9280 #ifdef GLYPH_DEBUG
9282 DEFUN ("imagep", Fimagep, Simagep, 1, 1, 0,
9283 doc: /* Value is non-nil if SPEC is a valid image specification. */)
9284 (Lisp_Object spec)
9286 return valid_image_p (spec) ? Qt : Qnil;
9290 DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
9291 (Lisp_Object spec)
9293 ptrdiff_t id = -1;
9295 if (valid_image_p (spec))
9296 id = lookup_image (SELECTED_FRAME (), spec);
9298 debug_print (spec);
9299 return make_number (id);
9302 #endif /* GLYPH_DEBUG */
9305 /***********************************************************************
9306 Initialization
9307 ***********************************************************************/
9309 DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 1, 1, 0,
9310 doc: /* Initialize image library implementing image type TYPE.
9311 Return non-nil if TYPE is a supported image type.
9313 If image libraries are loaded dynamically (currently only the case on
9314 MS-Windows), load the library for TYPE if it is not yet loaded, using
9315 the library file(s) specified by `dynamic-library-alist'. */)
9316 (Lisp_Object type)
9318 return lookup_image_type (type) ? Qt : Qnil;
9321 /* Look up image type TYPE, and return a pointer to its image_type
9322 structure. Return 0 if TYPE is not a known image type. */
9324 static struct image_type *
9325 lookup_image_type (Lisp_Object type)
9327 /* Types pbm and xbm are built-in and always available. */
9328 if (EQ (type, Qpbm))
9329 return define_image_type (&pbm_type);
9331 if (EQ (type, Qxbm))
9332 return define_image_type (&xbm_type);
9334 #if defined (HAVE_XPM) || defined (HAVE_NS)
9335 if (EQ (type, Qxpm))
9336 return define_image_type (&xpm_type);
9337 #endif
9339 #if defined (HAVE_JPEG) || defined (HAVE_NS)
9340 if (EQ (type, Qjpeg))
9341 return define_image_type (&jpeg_type);
9342 #endif
9344 #if defined (HAVE_TIFF) || defined (HAVE_NS)
9345 if (EQ (type, Qtiff))
9346 return define_image_type (&tiff_type);
9347 #endif
9349 #if defined (HAVE_GIF) || defined (HAVE_NS)
9350 if (EQ (type, Qgif))
9351 return define_image_type (&gif_type);
9352 #endif
9354 #if defined (HAVE_PNG) || defined (HAVE_NS)
9355 if (EQ (type, Qpng))
9356 return define_image_type (&png_type);
9357 #endif
9359 #if defined (HAVE_RSVG)
9360 if (EQ (type, Qsvg))
9361 return define_image_type (&svg_type);
9362 #endif
9364 #if defined (HAVE_IMAGEMAGICK)
9365 if (EQ (type, Qimagemagick))
9366 return define_image_type (&imagemagick_type);
9367 #endif
9369 #ifdef HAVE_GHOSTSCRIPT
9370 if (EQ (type, Qpostscript))
9371 return define_image_type (&gs_type);
9372 #endif
9374 return NULL;
9377 /* Reset image_types before dumping.
9378 Called from Fdump_emacs. */
9380 void
9381 reset_image_types (void)
9383 while (image_types)
9385 struct image_type *next = image_types->next;
9386 xfree (image_types);
9387 image_types = next;
9391 void
9392 syms_of_image (void)
9394 /* Initialize this only once; it will be reset before dumping. */
9395 image_types = NULL;
9397 /* Must be defined now because we're going to update it below, while
9398 defining the supported image types. */
9399 DEFVAR_LISP ("image-types", Vimage_types,
9400 doc: /* List of potentially supported image types.
9401 Each element of the list is a symbol for an image type, like 'jpeg or 'png.
9402 To check whether it is really supported, use `image-type-available-p'. */);
9403 Vimage_types = Qnil;
9405 DEFVAR_LISP ("max-image-size", Vmax_image_size,
9406 doc: /* Maximum size of images.
9407 Emacs will not load an image into memory if its pixel width or
9408 pixel height exceeds this limit.
9410 If the value is an integer, it directly specifies the maximum
9411 image height and width, measured in pixels. If it is a floating
9412 point number, it specifies the maximum image height and width
9413 as a ratio to the frame height and width. If the value is
9414 non-numeric, there is no explicit limit on the size of images. */);
9415 Vmax_image_size = make_float (MAX_IMAGE_SIZE);
9417 /* Other symbols. */
9418 DEFSYM (Qcount, "count");
9419 DEFSYM (Qextension_data, "extension-data");
9420 DEFSYM (Qdelay, "delay");
9422 /* Keywords. */
9423 DEFSYM (QCascent, ":ascent");
9424 DEFSYM (QCmargin, ":margin");
9425 DEFSYM (QCrelief, ":relief");
9426 DEFSYM (QCconversion, ":conversion");
9427 DEFSYM (QCcolor_symbols, ":color-symbols");
9428 DEFSYM (QCheuristic_mask, ":heuristic-mask");
9429 DEFSYM (QCindex, ":index");
9430 DEFSYM (QCgeometry, ":geometry");
9431 DEFSYM (QCcrop, ":crop");
9432 DEFSYM (QCrotation, ":rotation");
9433 DEFSYM (QCmatrix, ":matrix");
9434 DEFSYM (QCcolor_adjustment, ":color-adjustment");
9435 DEFSYM (QCmask, ":mask");
9437 /* Other symbols. */
9438 DEFSYM (Qlaplace, "laplace");
9439 DEFSYM (Qemboss, "emboss");
9440 DEFSYM (Qedge_detection, "edge-detection");
9441 DEFSYM (Qheuristic, "heuristic");
9443 DEFSYM (Qpostscript, "postscript");
9444 DEFSYM (QCmax_width, ":max-width");
9445 DEFSYM (QCmax_height, ":max-height");
9446 #ifdef HAVE_GHOSTSCRIPT
9447 ADD_IMAGE_TYPE (Qpostscript);
9448 DEFSYM (QCloader, ":loader");
9449 DEFSYM (QCbounding_box, ":bounding-box");
9450 DEFSYM (QCpt_width, ":pt-width");
9451 DEFSYM (QCpt_height, ":pt-height");
9452 #endif /* HAVE_GHOSTSCRIPT */
9454 #ifdef HAVE_NTGUI
9455 /* Versions of libpng, libgif, and libjpeg that we were compiled with,
9456 or -1 if no PNG/GIF support was compiled in. This is tested by
9457 w32-win.el to correctly set up the alist used to search for the
9458 respective image libraries. */
9459 DEFSYM (Qlibpng_version, "libpng-version");
9460 Fset (Qlibpng_version,
9461 #if HAVE_PNG
9462 make_number (PNG_LIBPNG_VER)
9463 #else
9464 make_number (-1)
9465 #endif
9467 DEFSYM (Qlibgif_version, "libgif-version");
9468 Fset (Qlibgif_version,
9469 #ifdef HAVE_GIF
9470 make_number (GIFLIB_MAJOR * 10000
9471 + GIFLIB_MINOR * 100
9472 + GIFLIB_RELEASE)
9473 #else
9474 make_number (-1)
9475 #endif
9477 DEFSYM (Qlibjpeg_version, "libjpeg-version");
9478 Fset (Qlibjpeg_version,
9479 #if HAVE_JPEG
9480 make_number (JPEG_LIB_VERSION)
9481 #else
9482 make_number (-1)
9483 #endif
9485 #endif
9487 DEFSYM (Qpbm, "pbm");
9488 ADD_IMAGE_TYPE (Qpbm);
9490 DEFSYM (Qxbm, "xbm");
9491 ADD_IMAGE_TYPE (Qxbm);
9493 #if defined (HAVE_XPM) || defined (HAVE_NS)
9494 DEFSYM (Qxpm, "xpm");
9495 ADD_IMAGE_TYPE (Qxpm);
9496 #endif
9498 #if defined (HAVE_JPEG) || defined (HAVE_NS)
9499 DEFSYM (Qjpeg, "jpeg");
9500 ADD_IMAGE_TYPE (Qjpeg);
9501 #endif
9503 #if defined (HAVE_TIFF) || defined (HAVE_NS)
9504 DEFSYM (Qtiff, "tiff");
9505 ADD_IMAGE_TYPE (Qtiff);
9506 #endif
9508 #if defined (HAVE_GIF) || defined (HAVE_NS)
9509 DEFSYM (Qgif, "gif");
9510 ADD_IMAGE_TYPE (Qgif);
9511 #endif
9513 #if defined (HAVE_PNG) || defined (HAVE_NS)
9514 DEFSYM (Qpng, "png");
9515 ADD_IMAGE_TYPE (Qpng);
9516 #endif
9518 #if defined (HAVE_IMAGEMAGICK)
9519 DEFSYM (Qimagemagick, "imagemagick");
9520 ADD_IMAGE_TYPE (Qimagemagick);
9521 #endif
9523 #if defined (HAVE_RSVG)
9524 DEFSYM (Qsvg, "svg");
9525 ADD_IMAGE_TYPE (Qsvg);
9526 #ifdef HAVE_NTGUI
9527 /* Other libraries used directly by svg code. */
9528 DEFSYM (Qgdk_pixbuf, "gdk-pixbuf");
9529 DEFSYM (Qglib, "glib");
9530 DEFSYM (Qgobject, "gobject");
9531 #endif /* HAVE_NTGUI */
9532 #endif /* HAVE_RSVG */
9534 defsubr (&Sinit_image_library);
9535 #ifdef HAVE_IMAGEMAGICK
9536 defsubr (&Simagemagick_types);
9537 #endif
9538 defsubr (&Sclear_image_cache);
9539 defsubr (&Simage_flush);
9540 defsubr (&Simage_size);
9541 defsubr (&Simage_mask_p);
9542 defsubr (&Simage_metadata);
9544 #ifdef GLYPH_DEBUG
9545 defsubr (&Simagep);
9546 defsubr (&Slookup_image);
9547 #endif
9549 DEFVAR_BOOL ("cross-disabled-images", cross_disabled_images,
9550 doc: /* Non-nil means always draw a cross over disabled images.
9551 Disabled images are those having a `:conversion disabled' property.
9552 A cross is always drawn on black & white displays. */);
9553 cross_disabled_images = 0;
9555 DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path,
9556 doc: /* List of directories to search for window system bitmap files. */);
9557 Vx_bitmap_file_path = decode_env_path (0, PATH_BITMAPS, 0);
9559 DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay,
9560 doc: /* Maximum time after which images are removed from the cache.
9561 When an image has not been displayed this many seconds, Emacs
9562 automatically removes it from the image cache. If the cache contains
9563 a large number of images, the actual eviction time may be shorter.
9564 The value can also be nil, meaning the cache is never cleared.
9566 The function `clear-image-cache' disregards this variable. */);
9567 Vimage_cache_eviction_delay = make_number (300);
9568 #ifdef HAVE_IMAGEMAGICK
9569 DEFVAR_INT ("imagemagick-render-type", imagemagick_render_type,
9570 doc: /* Integer indicating which ImageMagick rendering method to use.
9571 The options are:
9572 0 -- the default method (pixel pushing)
9573 1 -- a newer method ("MagickExportImagePixels") that may perform
9574 better (speed etc) in some cases, but has not been as thoroughly
9575 tested with Emacs as the default method. This method requires
9576 ImageMagick version 6.4.6 (approximately) or later.
9577 */);
9578 /* MagickExportImagePixels is in 6.4.6-9, but not 6.4.4-10. */
9579 imagemagick_render_type = 0;
9580 #endif