* dispextern.h, image.c (x_bitmap_height, x_bitmap_width): Now static.
[emacs.git] / src / image.c
blob6691cfc8a10fe9e671fdd76ac8f07ed6bbfded3e
1 /* Functions for image support on window system.
3 Copyright (C) 1989, 1992-2013 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 #ifdef HAVE_PNG
25 #if defined HAVE_LIBPNG_PNG_H
26 # include <libpng/png.h>
27 #else
28 # include <png.h>
29 #endif
30 #endif
32 #include <setjmp.h>
33 #include <c-ctype.h>
35 #include "lisp.h"
36 #include "frame.h"
37 #include "window.h"
38 #include "dispextern.h"
39 #include "blockinput.h"
40 #include "systime.h"
41 #include <epaths.h>
42 #include "character.h"
43 #include "coding.h"
44 #include "termhooks.h"
45 #include "font.h"
47 #ifdef HAVE_SYS_STAT_H
48 #include <sys/stat.h>
49 #endif /* HAVE_SYS_STAT_H */
51 #ifdef HAVE_SYS_TYPES_H
52 #include <sys/types.h>
53 #endif /* HAVE_SYS_TYPES_H */
55 #ifdef HAVE_WINDOW_SYSTEM
56 #include TERM_HEADER
57 #endif /* HAVE_WINDOW_SYSTEM */
59 #ifdef HAVE_X_WINDOWS
60 #define COLOR_TABLE_SUPPORT 1
62 typedef struct x_bitmap_record Bitmap_Record;
63 #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
64 #define NO_PIXMAP None
66 #define PIX_MASK_RETAIN 0
67 #define PIX_MASK_DRAW 1
68 #endif /* HAVE_X_WINDOWS */
70 #ifdef HAVE_NTGUI
72 /* We need (or want) w32.h only when we're _not_ compiling for Cygwin. */
73 #ifdef WINDOWSNT
74 # include "w32.h"
75 #endif
77 /* W32_TODO : Color tables on W32. */
78 #undef COLOR_TABLE_SUPPORT
80 typedef struct w32_bitmap_record Bitmap_Record;
81 #define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y)
82 #define NO_PIXMAP 0
84 #define PIX_MASK_RETAIN 0
85 #define PIX_MASK_DRAW 1
87 #define x_defined_color w32_defined_color
88 #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
90 /* Versions of libpng and libgif that we were compiled with, or -1 if
91 no PNG/GIF support was compiled in. This is tested by w32-win.el
92 to correctly set up the alist used to search for the respective
93 image libraries. */
94 Lisp_Object Qlibpng_version, Qlibgif_version;
95 #endif /* HAVE_NTGUI */
97 #ifdef HAVE_NS
98 #undef COLOR_TABLE_SUPPORT
100 typedef struct ns_bitmap_record Bitmap_Record;
102 #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
103 #define NO_PIXMAP 0
105 #define PIX_MASK_RETAIN 0
106 #define PIX_MASK_DRAW 1
108 #define x_defined_color(f, name, color_def, alloc) \
109 ns_defined_color (f, name, color_def, alloc, 0)
110 #define DefaultDepthOfScreen(screen) x_display_list->n_planes
111 #endif /* HAVE_NS */
114 /* The symbol `postscript' identifying images of this type. */
116 static Lisp_Object Qpostscript;
118 static void x_disable_image (struct frame *, struct image *);
119 static void x_edge_detection (struct frame *, struct image *, Lisp_Object,
120 Lisp_Object);
122 static void init_color_table (void);
123 static unsigned long lookup_rgb_color (struct frame *f, int r, int g, int b);
124 #ifdef COLOR_TABLE_SUPPORT
125 static void free_color_table (void);
126 static unsigned long *colors_in_color_table (int *n);
127 #endif
129 static Lisp_Object QCmax_width, QCmax_height;
131 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
132 id, which is just an int that this section returns. Bitmaps are
133 reference counted so they can be shared among frames.
135 Bitmap indices are guaranteed to be > 0, so a negative number can
136 be used to indicate no bitmap.
138 If you use x_create_bitmap_from_data, then you must keep track of
139 the bitmaps yourself. That is, creating a bitmap from the same
140 data more than once will not be caught. */
142 #ifdef HAVE_NS
143 /* Use with images created by ns_image_for_XPM. */
144 static unsigned long
145 XGetPixel (XImagePtr ximage, int x, int y)
147 return ns_get_pixel (ximage, x, y);
150 /* Use with images created by ns_image_for_XPM; alpha set to 1;
151 pixel is assumed to be in RGB form. */
152 static void
153 XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel)
155 ns_put_pixel (ximage, x, y, pixel);
157 #endif /* HAVE_NS */
160 /* Functions to access the contents of a bitmap, given an id. */
162 static int
163 x_bitmap_height (struct frame *f, ptrdiff_t id)
165 return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].height;
168 static int
169 x_bitmap_width (struct frame *f, ptrdiff_t id)
171 return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].width;
174 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
175 ptrdiff_t
176 x_bitmap_pixmap (struct frame *f, ptrdiff_t id)
178 /* HAVE_NTGUI needs the explicit cast here. */
179 return (ptrdiff_t) FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
181 #endif
183 #ifdef HAVE_X_WINDOWS
185 x_bitmap_mask (struct frame *f, ptrdiff_t id)
187 return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].mask;
189 #endif
191 /* Allocate a new bitmap record. Returns index of new record. */
193 static ptrdiff_t
194 x_allocate_bitmap_record (struct frame *f)
196 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
197 ptrdiff_t i;
199 if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size)
200 return ++dpyinfo->bitmaps_last;
202 for (i = 0; i < dpyinfo->bitmaps_size; ++i)
203 if (dpyinfo->bitmaps[i].refcount == 0)
204 return i + 1;
206 dpyinfo->bitmaps =
207 xpalloc (dpyinfo->bitmaps, &dpyinfo->bitmaps_size,
208 10, -1, sizeof *dpyinfo->bitmaps);
209 return ++dpyinfo->bitmaps_last;
212 /* Add one reference to the reference count of the bitmap with id ID. */
214 void
215 x_reference_bitmap (struct frame *f, ptrdiff_t id)
217 ++FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
220 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
222 ptrdiff_t
223 x_create_bitmap_from_data (struct frame *f, char *bits, unsigned int width, unsigned int height)
225 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
226 ptrdiff_t id;
228 #ifdef HAVE_X_WINDOWS
229 Pixmap bitmap;
230 bitmap = XCreateBitmapFromData (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
231 bits, width, height);
232 if (! bitmap)
233 return -1;
234 #endif /* HAVE_X_WINDOWS */
236 #ifdef HAVE_NTGUI
237 Pixmap bitmap;
238 bitmap = CreateBitmap (width, height,
239 FRAME_DISPLAY_INFO (XFRAME (frame))->n_planes,
240 FRAME_DISPLAY_INFO (XFRAME (frame))->n_cbits,
241 bits);
242 if (! bitmap)
243 return -1;
244 #endif /* HAVE_NTGUI */
246 #ifdef HAVE_NS
247 void *bitmap = ns_image_from_XBM (bits, width, height);
248 if (!bitmap)
249 return -1;
250 #endif
252 id = x_allocate_bitmap_record (f);
254 #ifdef HAVE_NS
255 dpyinfo->bitmaps[id - 1].img = bitmap;
256 dpyinfo->bitmaps[id - 1].depth = 1;
257 #endif
259 dpyinfo->bitmaps[id - 1].file = NULL;
260 dpyinfo->bitmaps[id - 1].height = height;
261 dpyinfo->bitmaps[id - 1].width = width;
262 dpyinfo->bitmaps[id - 1].refcount = 1;
264 #ifdef HAVE_X_WINDOWS
265 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
266 dpyinfo->bitmaps[id - 1].have_mask = 0;
267 dpyinfo->bitmaps[id - 1].depth = 1;
268 #endif /* HAVE_X_WINDOWS */
270 #ifdef HAVE_NTGUI
271 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
272 dpyinfo->bitmaps[id - 1].hinst = NULL;
273 dpyinfo->bitmaps[id - 1].depth = 1;
274 #endif /* HAVE_NTGUI */
276 return id;
279 /* Create bitmap from file FILE for frame F. */
281 ptrdiff_t
282 x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
284 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
286 #ifdef HAVE_NTGUI
287 return -1; /* W32_TODO : bitmap support */
288 #endif /* HAVE_NTGUI */
290 #ifdef HAVE_NS
291 ptrdiff_t id;
292 void *bitmap = ns_image_from_file (file);
294 if (!bitmap)
295 return -1;
298 id = x_allocate_bitmap_record (f);
299 dpyinfo->bitmaps[id - 1].img = bitmap;
300 dpyinfo->bitmaps[id - 1].refcount = 1;
301 dpyinfo->bitmaps[id - 1].file = xlispstrdup (file);
302 dpyinfo->bitmaps[id - 1].depth = 1;
303 dpyinfo->bitmaps[id - 1].height = ns_image_width (bitmap);
304 dpyinfo->bitmaps[id - 1].width = ns_image_height (bitmap);
305 return id;
306 #endif
308 #ifdef HAVE_X_WINDOWS
309 unsigned int width, height;
310 Pixmap bitmap;
311 int xhot, yhot, result;
312 ptrdiff_t id;
313 Lisp_Object found;
314 char *filename;
316 /* Look for an existing bitmap with the same name. */
317 for (id = 0; id < dpyinfo->bitmaps_last; ++id)
319 if (dpyinfo->bitmaps[id].refcount
320 && dpyinfo->bitmaps[id].file
321 && !strcmp (dpyinfo->bitmaps[id].file, SSDATA (file)))
323 ++dpyinfo->bitmaps[id].refcount;
324 return id + 1;
328 /* Search bitmap-file-path for the file, if appropriate. */
329 if (openp (Vx_bitmap_file_path, file, Qnil, &found, make_number (R_OK)) < 0)
330 return -1;
332 filename = SSDATA (found);
334 result = XReadBitmapFile (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
335 filename, &width, &height, &bitmap, &xhot, &yhot);
336 if (result != BitmapSuccess)
337 return -1;
339 id = x_allocate_bitmap_record (f);
340 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
341 dpyinfo->bitmaps[id - 1].have_mask = 0;
342 dpyinfo->bitmaps[id - 1].refcount = 1;
343 dpyinfo->bitmaps[id - 1].file = xlispstrdup (file);
344 dpyinfo->bitmaps[id - 1].depth = 1;
345 dpyinfo->bitmaps[id - 1].height = height;
346 dpyinfo->bitmaps[id - 1].width = width;
348 return id;
349 #endif /* HAVE_X_WINDOWS */
352 /* Free bitmap B. */
354 static void
355 free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm)
357 #ifdef HAVE_X_WINDOWS
358 XFreePixmap (dpyinfo->display, bm->pixmap);
359 if (bm->have_mask)
360 XFreePixmap (dpyinfo->display, bm->mask);
361 #endif /* HAVE_X_WINDOWS */
363 #ifdef HAVE_NTGUI
364 DeleteObject (bm->pixmap);
365 #endif /* HAVE_NTGUI */
367 #ifdef HAVE_NS
368 ns_release_object (bm->img);
369 #endif
371 if (bm->file)
373 xfree (bm->file);
374 bm->file = NULL;
378 /* Remove reference to bitmap with id number ID. */
380 void
381 x_destroy_bitmap (struct frame *f, ptrdiff_t id)
383 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
385 if (id > 0)
387 Bitmap_Record *bm = &dpyinfo->bitmaps[id - 1];
389 if (--bm->refcount == 0)
391 block_input ();
392 free_bitmap_record (dpyinfo, bm);
393 unblock_input ();
398 /* Free all the bitmaps for the display specified by DPYINFO. */
400 void
401 x_destroy_all_bitmaps (Display_Info *dpyinfo)
403 ptrdiff_t i;
404 Bitmap_Record *bm = dpyinfo->bitmaps;
406 for (i = 0; i < dpyinfo->bitmaps_last; i++, bm++)
407 if (bm->refcount > 0)
408 free_bitmap_record (dpyinfo, bm);
410 dpyinfo->bitmaps_last = 0;
413 static bool x_create_x_image_and_pixmap (struct frame *, int, int, int,
414 XImagePtr *, Pixmap *);
415 static void x_destroy_x_image (XImagePtr ximg);
417 #ifdef HAVE_NTGUI
418 static XImagePtr_or_DC image_get_x_image_or_dc (struct frame *, struct image *,
419 bool, HGDIOBJ *);
420 static void image_unget_x_image_or_dc (struct image *, bool, XImagePtr_or_DC,
421 HGDIOBJ);
422 #else
423 static XImagePtr image_get_x_image (struct frame *, struct image *, bool);
424 static void image_unget_x_image (struct image *, bool, XImagePtr);
425 #define image_get_x_image_or_dc(f, img, mask_p, dummy) \
426 image_get_x_image (f, img, mask_p)
427 #define image_unget_x_image_or_dc(img, mask_p, ximg, dummy) \
428 image_unget_x_image (img, mask_p, ximg)
429 #endif
431 #ifdef HAVE_X_WINDOWS
433 static void image_sync_to_pixmaps (struct frame *, struct image *);
435 /* Useful functions defined in the section
436 `Image type independent image structures' below. */
438 static unsigned long four_corners_best (XImagePtr ximg,
439 int *corners,
440 unsigned long width,
441 unsigned long height);
444 /* Create a mask of a bitmap. Note is this not a perfect mask.
445 It's nicer with some borders in this context */
447 void
448 x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
450 Pixmap pixmap, mask;
451 XImagePtr ximg, mask_img;
452 unsigned long width, height;
453 bool result;
454 unsigned long bg;
455 unsigned long x, y, xp, xm, yp, ym;
456 GC gc;
458 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
460 if (!(id > 0))
461 return;
463 pixmap = x_bitmap_pixmap (f, id);
464 width = x_bitmap_width (f, id);
465 height = x_bitmap_height (f, id);
467 block_input ();
468 ximg = XGetImage (FRAME_X_DISPLAY (f), pixmap, 0, 0, width, height,
469 ~0, ZPixmap);
471 if (!ximg)
473 unblock_input ();
474 return;
477 result = x_create_x_image_and_pixmap (f, width, height, 1, &mask_img, &mask);
479 unblock_input ();
480 if (!result)
482 XDestroyImage (ximg);
483 return;
486 bg = four_corners_best (ximg, NULL, width, height);
488 for (y = 0; y < ximg->height; ++y)
490 for (x = 0; x < ximg->width; ++x)
492 xp = x != ximg->width - 1 ? x + 1 : 0;
493 xm = x != 0 ? x - 1 : ximg->width - 1;
494 yp = y != ximg->height - 1 ? y + 1 : 0;
495 ym = y != 0 ? y - 1 : ximg->height - 1;
496 if (XGetPixel (ximg, x, y) == bg
497 && XGetPixel (ximg, x, yp) == bg
498 && XGetPixel (ximg, x, ym) == bg
499 && XGetPixel (ximg, xp, y) == bg
500 && XGetPixel (ximg, xp, yp) == bg
501 && XGetPixel (ximg, xp, ym) == bg
502 && XGetPixel (ximg, xm, y) == bg
503 && XGetPixel (ximg, xm, yp) == bg
504 && XGetPixel (ximg, xm, ym) == bg)
505 XPutPixel (mask_img, x, y, 0);
506 else
507 XPutPixel (mask_img, x, y, 1);
511 eassert (input_blocked_p ());
512 gc = XCreateGC (FRAME_X_DISPLAY (f), mask, 0, NULL);
513 XPutImage (FRAME_X_DISPLAY (f), mask, gc, mask_img, 0, 0, 0, 0,
514 width, height);
515 XFreeGC (FRAME_X_DISPLAY (f), gc);
517 dpyinfo->bitmaps[id - 1].have_mask = 1;
518 dpyinfo->bitmaps[id - 1].mask = mask;
520 XDestroyImage (ximg);
521 x_destroy_x_image (mask_img);
524 #endif /* HAVE_X_WINDOWS */
527 /***********************************************************************
528 Image types
529 ***********************************************************************/
531 /* List of supported image types. Use define_image_type to add new
532 types. Use lookup_image_type to find a type for a given symbol. */
534 static struct image_type *image_types;
536 /* The symbol `xbm' which is used as the type symbol for XBM images. */
538 static Lisp_Object Qxbm;
540 /* Keywords. */
542 Lisp_Object QCascent, QCmargin, QCrelief;
543 Lisp_Object QCconversion;
544 static Lisp_Object QCheuristic_mask;
545 static Lisp_Object QCcolor_symbols;
546 static Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask, QCgeometry;
547 static Lisp_Object QCcrop, QCrotation;
549 /* Other symbols. */
551 static Lisp_Object Qcount, Qextension_data, Qdelay;
552 static Lisp_Object Qlaplace, Qemboss, Qedge_detection, Qheuristic;
554 /* Forward function prototypes. */
556 static struct image_type *lookup_image_type (Lisp_Object);
557 static void x_laplace (struct frame *, struct image *);
558 static void x_emboss (struct frame *, struct image *);
559 static void x_build_heuristic_mask (struct frame *, struct image *,
560 Lisp_Object);
561 #ifdef WINDOWSNT
562 #define CACHE_IMAGE_TYPE(type, status) \
563 do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
564 #else
565 #define CACHE_IMAGE_TYPE(type, status)
566 #endif
568 #define ADD_IMAGE_TYPE(type) \
569 do { Vimage_types = Fcons (type, Vimage_types); } while (0)
571 /* Define a new image type from TYPE. This adds a copy of TYPE to
572 image_types and caches the loading status of TYPE. */
574 static struct image_type *
575 define_image_type (struct image_type *type)
577 struct image_type *p = NULL;
578 Lisp_Object target_type = *type->type;
579 bool type_valid = 1;
581 block_input ();
583 for (p = image_types; p; p = p->next)
584 if (EQ (*p->type, target_type))
585 goto done;
587 if (type->init)
589 #if defined HAVE_NTGUI && defined WINDOWSNT
590 /* If we failed to load the library before, don't try again. */
591 Lisp_Object tested = Fassq (target_type, Vlibrary_cache);
592 if (CONSP (tested) && NILP (XCDR (tested)))
593 type_valid = 0;
594 else
595 #endif
597 type_valid = type->init ();
598 CACHE_IMAGE_TYPE (target_type, type_valid ? Qt : Qnil);
602 if (type_valid)
604 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
605 The initialized data segment is read-only. */
606 p = xmalloc (sizeof *p);
607 *p = *type;
608 p->next = image_types;
609 image_types = p;
612 done:
613 unblock_input ();
614 return p;
618 /* Value is true if OBJECT is a valid Lisp image specification. A
619 valid image specification is a list whose car is the symbol
620 `image', and whose rest is a property list. The property list must
621 contain a value for key `:type'. That value must be the name of a
622 supported image type. The rest of the property list depends on the
623 image type. */
625 bool
626 valid_image_p (Lisp_Object object)
628 bool valid_p = 0;
630 if (IMAGEP (object))
632 Lisp_Object tem;
634 for (tem = XCDR (object); CONSP (tem); tem = XCDR (tem))
635 if (EQ (XCAR (tem), QCtype))
637 tem = XCDR (tem);
638 if (CONSP (tem) && SYMBOLP (XCAR (tem)))
640 struct image_type *type;
641 type = lookup_image_type (XCAR (tem));
642 if (type)
643 valid_p = type->valid_p (object);
646 break;
650 return valid_p;
654 /* Log error message with format string FORMAT and argument ARG.
655 Signaling an error, e.g. when an image cannot be loaded, is not a
656 good idea because this would interrupt redisplay, and the error
657 message display would lead to another redisplay. This function
658 therefore simply displays a message. */
660 static void
661 image_error (const char *format, Lisp_Object arg1, Lisp_Object arg2)
663 add_to_log (format, arg1, arg2);
668 /***********************************************************************
669 Image specifications
670 ***********************************************************************/
672 enum image_value_type
674 IMAGE_DONT_CHECK_VALUE_TYPE,
675 IMAGE_STRING_VALUE,
676 IMAGE_STRING_OR_NIL_VALUE,
677 IMAGE_SYMBOL_VALUE,
678 IMAGE_POSITIVE_INTEGER_VALUE,
679 IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR,
680 IMAGE_NON_NEGATIVE_INTEGER_VALUE,
681 IMAGE_ASCENT_VALUE,
682 IMAGE_INTEGER_VALUE,
683 IMAGE_FUNCTION_VALUE,
684 IMAGE_NUMBER_VALUE,
685 IMAGE_BOOL_VALUE
688 /* Structure used when parsing image specifications. */
690 struct image_keyword
692 /* Name of keyword. */
693 const char *name;
695 /* The type of value allowed. */
696 enum image_value_type type;
698 /* True means key must be present. */
699 bool mandatory_p;
701 /* Used to recognize duplicate keywords in a property list. */
702 int count;
704 /* The value that was found. */
705 Lisp_Object value;
709 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
710 has the format (image KEYWORD VALUE ...). One of the keyword/
711 value pairs must be `:type TYPE'. KEYWORDS is a vector of
712 image_keywords structures of size NKEYWORDS describing other
713 allowed keyword/value pairs. Value is true if SPEC is valid. */
715 static bool
716 parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
717 int nkeywords, Lisp_Object type)
719 int i;
720 Lisp_Object plist;
722 if (!IMAGEP (spec))
723 return 0;
725 plist = XCDR (spec);
726 while (CONSP (plist))
728 Lisp_Object key, value;
730 /* First element of a pair must be a symbol. */
731 key = XCAR (plist);
732 plist = XCDR (plist);
733 if (!SYMBOLP (key))
734 return 0;
736 /* There must follow a value. */
737 if (!CONSP (plist))
738 return 0;
739 value = XCAR (plist);
740 plist = XCDR (plist);
742 /* Find key in KEYWORDS. Error if not found. */
743 for (i = 0; i < nkeywords; ++i)
744 if (strcmp (keywords[i].name, SSDATA (SYMBOL_NAME (key))) == 0)
745 break;
747 if (i == nkeywords)
748 continue;
750 /* Record that we recognized the keyword. If a keywords
751 was found more than once, it's an error. */
752 keywords[i].value = value;
753 if (keywords[i].count > 1)
754 return 0;
755 ++keywords[i].count;
757 /* Check type of value against allowed type. */
758 switch (keywords[i].type)
760 case IMAGE_STRING_VALUE:
761 if (!STRINGP (value))
762 return 0;
763 break;
765 case IMAGE_STRING_OR_NIL_VALUE:
766 if (!STRINGP (value) && !NILP (value))
767 return 0;
768 break;
770 case IMAGE_SYMBOL_VALUE:
771 if (!SYMBOLP (value))
772 return 0;
773 break;
775 case IMAGE_POSITIVE_INTEGER_VALUE:
776 if (! RANGED_INTEGERP (1, value, INT_MAX))
777 return 0;
778 break;
780 case IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR:
781 if (RANGED_INTEGERP (0, value, INT_MAX))
782 break;
783 if (CONSP (value)
784 && RANGED_INTEGERP (0, XCAR (value), INT_MAX)
785 && RANGED_INTEGERP (0, XCDR (value), INT_MAX))
786 break;
787 return 0;
789 case IMAGE_ASCENT_VALUE:
790 if (SYMBOLP (value) && EQ (value, Qcenter))
791 break;
792 else if (RANGED_INTEGERP (0, value, 100))
793 break;
794 return 0;
796 case IMAGE_NON_NEGATIVE_INTEGER_VALUE:
797 /* Unlike the other integer-related cases, this one does not
798 verify that VALUE fits in 'int'. This is because callers
799 want EMACS_INT. */
800 if (!INTEGERP (value) || XINT (value) < 0)
801 return 0;
802 break;
804 case IMAGE_DONT_CHECK_VALUE_TYPE:
805 break;
807 case IMAGE_FUNCTION_VALUE:
808 value = indirect_function (value);
809 if (!NILP (Ffunctionp (value)))
810 break;
811 return 0;
813 case IMAGE_NUMBER_VALUE:
814 if (!INTEGERP (value) && !FLOATP (value))
815 return 0;
816 break;
818 case IMAGE_INTEGER_VALUE:
819 if (! TYPE_RANGED_INTEGERP (int, value))
820 return 0;
821 break;
823 case IMAGE_BOOL_VALUE:
824 if (!NILP (value) && !EQ (value, Qt))
825 return 0;
826 break;
828 default:
829 emacs_abort ();
830 break;
833 if (EQ (key, QCtype) && !EQ (type, value))
834 return 0;
837 /* Check that all mandatory fields are present. */
838 for (i = 0; i < nkeywords; ++i)
839 if (keywords[i].mandatory_p && keywords[i].count == 0)
840 return 0;
842 return NILP (plist);
846 /* Return the value of KEY in image specification SPEC. Value is nil
847 if KEY is not present in SPEC. Set *FOUND depending on whether KEY
848 was found in SPEC. */
850 static Lisp_Object
851 image_spec_value (Lisp_Object spec, Lisp_Object key, bool *found)
853 Lisp_Object tail;
855 eassert (valid_image_p (spec));
857 for (tail = XCDR (spec);
858 CONSP (tail) && CONSP (XCDR (tail));
859 tail = XCDR (XCDR (tail)))
861 if (EQ (XCAR (tail), key))
863 if (found)
864 *found = 1;
865 return XCAR (XCDR (tail));
869 if (found)
870 *found = 0;
871 return Qnil;
875 DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0,
876 doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
877 PIXELS non-nil means return the size in pixels, otherwise return the
878 size in canonical character units.
879 FRAME is the frame on which the image will be displayed. FRAME nil
880 or omitted means use the selected frame. */)
881 (Lisp_Object spec, Lisp_Object pixels, Lisp_Object frame)
883 Lisp_Object size;
885 size = Qnil;
886 if (valid_image_p (spec))
888 struct frame *f = decode_window_system_frame (frame);
889 ptrdiff_t id = lookup_image (f, spec);
890 struct image *img = IMAGE_FROM_ID (f, id);
891 int width = img->width + 2 * img->hmargin;
892 int height = img->height + 2 * img->vmargin;
894 if (NILP (pixels))
895 size = Fcons (make_float ((double) width / FRAME_COLUMN_WIDTH (f)),
896 make_float ((double) height / FRAME_LINE_HEIGHT (f)));
897 else
898 size = Fcons (make_number (width), make_number (height));
900 else
901 error ("Invalid image specification");
903 return size;
907 DEFUN ("image-mask-p", Fimage_mask_p, Simage_mask_p, 1, 2, 0,
908 doc: /* Return t if image SPEC has a mask bitmap.
909 FRAME is the frame on which the image will be displayed. FRAME nil
910 or omitted means use the selected frame. */)
911 (Lisp_Object spec, Lisp_Object frame)
913 Lisp_Object mask;
915 mask = Qnil;
916 if (valid_image_p (spec))
918 struct frame *f = decode_window_system_frame (frame);
919 ptrdiff_t id = lookup_image (f, spec);
920 struct image *img = IMAGE_FROM_ID (f, id);
921 if (img->mask)
922 mask = Qt;
924 else
925 error ("Invalid image specification");
927 return mask;
930 DEFUN ("image-metadata", Fimage_metadata, Simage_metadata, 1, 2, 0,
931 doc: /* Return metadata for image SPEC.
932 FRAME is the frame on which the image will be displayed. FRAME nil
933 or omitted means use the selected frame. */)
934 (Lisp_Object spec, Lisp_Object frame)
936 Lisp_Object ext;
938 ext = Qnil;
939 if (valid_image_p (spec))
941 struct frame *f = decode_window_system_frame (frame);
942 ptrdiff_t id = lookup_image (f, spec);
943 struct image *img = IMAGE_FROM_ID (f, id);
944 ext = img->lisp_data;
947 return ext;
951 /***********************************************************************
952 Image type independent image structures
953 ***********************************************************************/
955 #define MAX_IMAGE_SIZE 10.0
956 /* Allocate and return a new image structure for image specification
957 SPEC. SPEC has a hash value of HASH. */
959 static struct image *
960 make_image (Lisp_Object spec, EMACS_UINT hash)
962 struct image *img = xzalloc (sizeof *img);
963 Lisp_Object file = image_spec_value (spec, QCfile, NULL);
965 eassert (valid_image_p (spec));
966 img->dependencies = NILP (file) ? Qnil : list1 (file);
967 img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL));
968 eassert (img->type != NULL);
969 img->spec = spec;
970 img->lisp_data = Qnil;
971 img->ascent = DEFAULT_IMAGE_ASCENT;
972 img->hash = hash;
973 img->corners[BOT_CORNER] = -1; /* Full image */
974 return img;
978 /* Free image IMG which was used on frame F, including its resources. */
980 static void
981 free_image (struct frame *f, struct image *img)
983 if (img)
985 struct image_cache *c = FRAME_IMAGE_CACHE (f);
987 /* Remove IMG from the hash table of its cache. */
988 if (img->prev)
989 img->prev->next = img->next;
990 else
991 c->buckets[img->hash % IMAGE_CACHE_BUCKETS_SIZE] = img->next;
993 if (img->next)
994 img->next->prev = img->prev;
996 c->images[img->id] = NULL;
998 /* Free resources, then free IMG. */
999 img->type->free (f, img);
1000 xfree (img);
1004 /* Return true if the given widths and heights are valid for display. */
1006 static bool
1007 check_image_size (struct frame *f, int width, int height)
1009 int w, h;
1011 if (width <= 0 || height <= 0)
1012 return 0;
1014 if (INTEGERP (Vmax_image_size))
1015 return (width <= XINT (Vmax_image_size)
1016 && height <= XINT (Vmax_image_size));
1017 else if (FLOATP (Vmax_image_size))
1019 if (f != NULL)
1021 w = FRAME_PIXEL_WIDTH (f);
1022 h = FRAME_PIXEL_HEIGHT (f);
1024 else
1025 w = h = 1024; /* Arbitrary size for unknown frame. */
1026 return (width <= XFLOAT_DATA (Vmax_image_size) * w
1027 && height <= XFLOAT_DATA (Vmax_image_size) * h);
1029 else
1030 return 1;
1033 /* Prepare image IMG for display on frame F. Must be called before
1034 drawing an image. */
1036 void
1037 prepare_image_for_display (struct frame *f, struct image *img)
1039 /* We're about to display IMG, so set its timestamp to `now'. */
1040 img->timestamp = current_timespec ();
1042 /* If IMG doesn't have a pixmap yet, load it now, using the image
1043 type dependent loader function. */
1044 if (img->pixmap == NO_PIXMAP && !img->load_failed_p)
1045 img->load_failed_p = ! img->type->load (f, img);
1047 #ifdef HAVE_X_WINDOWS
1048 if (!img->load_failed_p)
1050 block_input ();
1051 image_sync_to_pixmaps (f, img);
1052 unblock_input ();
1054 #endif
1058 /* Value is the number of pixels for the ascent of image IMG when
1059 drawn in face FACE. */
1062 image_ascent (struct image *img, struct face *face, struct glyph_slice *slice)
1064 int height;
1065 int ascent;
1067 if (slice->height == img->height)
1068 height = img->height + img->vmargin;
1069 else if (slice->y == 0)
1070 height = slice->height + img->vmargin;
1071 else
1072 height = slice->height;
1074 if (img->ascent == CENTERED_IMAGE_ASCENT)
1076 if (face->font)
1078 #ifdef HAVE_NTGUI
1079 /* W32 specific version. Why?. ++kfs */
1080 ascent = height / 2 - (FONT_DESCENT (face->font)
1081 - FONT_BASE (face->font)) / 2;
1082 #else
1083 /* This expression is arranged so that if the image can't be
1084 exactly centered, it will be moved slightly up. This is
1085 because a typical font is `top-heavy' (due to the presence
1086 uppercase letters), so the image placement should err towards
1087 being top-heavy too. It also just generally looks better. */
1088 ascent = (height + FONT_BASE (face->font)
1089 - FONT_DESCENT (face->font) + 1) / 2;
1090 #endif /* HAVE_NTGUI */
1092 else
1093 ascent = height / 2;
1095 else
1096 ascent = height * (img->ascent / 100.0);
1098 return ascent;
1102 /* Image background colors. */
1104 /* Find the "best" corner color of a bitmap.
1105 On W32, XIMG is assumed to a device context with the bitmap selected. */
1107 static RGB_PIXEL_COLOR
1108 four_corners_best (XImagePtr_or_DC ximg, int *corners,
1109 unsigned long width, unsigned long height)
1111 RGB_PIXEL_COLOR corner_pixels[4], best IF_LINT (= 0);
1112 int i, best_count;
1114 if (corners && corners[BOT_CORNER] >= 0)
1116 /* Get the colors at the corner_pixels of ximg. */
1117 corner_pixels[0] = GET_PIXEL (ximg, corners[LEFT_CORNER], corners[TOP_CORNER]);
1118 corner_pixels[1] = GET_PIXEL (ximg, corners[RIGHT_CORNER] - 1, corners[TOP_CORNER]);
1119 corner_pixels[2] = GET_PIXEL (ximg, corners[RIGHT_CORNER] - 1, corners[BOT_CORNER] - 1);
1120 corner_pixels[3] = GET_PIXEL (ximg, corners[LEFT_CORNER], corners[BOT_CORNER] - 1);
1122 else
1124 /* Get the colors at the corner_pixels of ximg. */
1125 corner_pixels[0] = GET_PIXEL (ximg, 0, 0);
1126 corner_pixels[1] = GET_PIXEL (ximg, width - 1, 0);
1127 corner_pixels[2] = GET_PIXEL (ximg, width - 1, height - 1);
1128 corner_pixels[3] = GET_PIXEL (ximg, 0, height - 1);
1130 /* Choose the most frequently found color as background. */
1131 for (i = best_count = 0; i < 4; ++i)
1133 int j, n;
1135 for (j = n = 0; j < 4; ++j)
1136 if (corner_pixels[i] == corner_pixels[j])
1137 ++n;
1139 if (n > best_count)
1140 best = corner_pixels[i], best_count = n;
1143 return best;
1146 /* Portability macros */
1148 #ifdef HAVE_NTGUI
1150 #define Free_Pixmap(display, pixmap) \
1151 DeleteObject (pixmap)
1153 #elif defined (HAVE_NS)
1155 #define Free_Pixmap(display, pixmap) \
1156 ns_release_object (pixmap)
1158 #else
1160 #define Free_Pixmap(display, pixmap) \
1161 XFreePixmap (display, pixmap)
1163 #endif /* !HAVE_NTGUI && !HAVE_NS */
1166 /* Return the `background' field of IMG. If IMG doesn't have one yet,
1167 it is guessed heuristically. If non-zero, XIMG is an existing
1168 XImage object (or device context with the image selected on W32) to
1169 use for the heuristic. */
1171 RGB_PIXEL_COLOR
1172 image_background (struct image *img, struct frame *f, XImagePtr_or_DC ximg)
1174 if (! img->background_valid)
1175 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1177 bool free_ximg = !ximg;
1178 #ifdef HAVE_NTGUI
1179 HGDIOBJ prev;
1180 #endif /* HAVE_NTGUI */
1182 if (free_ximg)
1183 ximg = image_get_x_image_or_dc (f, img, 0, &prev);
1185 img->background = four_corners_best (ximg, img->corners, img->width, img->height);
1187 if (free_ximg)
1188 image_unget_x_image_or_dc (img, 0, ximg, prev);
1190 img->background_valid = 1;
1193 return img->background;
1196 /* Return the `background_transparent' field of IMG. If IMG doesn't
1197 have one yet, it is guessed heuristically. If non-zero, MASK is an
1198 existing XImage object to use for the heuristic. */
1201 image_background_transparent (struct image *img, struct frame *f, XImagePtr_or_DC mask)
1203 if (! img->background_transparent_valid)
1204 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1206 if (img->mask)
1208 bool free_mask = !mask;
1209 #ifdef HAVE_NTGUI
1210 HGDIOBJ prev;
1211 #endif /* HAVE_NTGUI */
1213 if (free_mask)
1214 mask = image_get_x_image_or_dc (f, img, 1, &prev);
1216 img->background_transparent
1217 = (four_corners_best (mask, img->corners, img->width, img->height) == PIX_MASK_RETAIN);
1219 if (free_mask)
1220 image_unget_x_image_or_dc (img, 1, mask, prev);
1222 else
1223 img->background_transparent = 0;
1225 img->background_transparent_valid = 1;
1228 return img->background_transparent;
1232 /***********************************************************************
1233 Helper functions for X image types
1234 ***********************************************************************/
1236 /* Clear X resources of image IMG on frame F according to FLAGS.
1237 FLAGS is bitwise-or of the following masks:
1238 CLEAR_IMAGE_PIXMAP free the pixmap if any.
1239 CLEAR_IMAGE_MASK means clear the mask pixmap if any.
1240 CLEAR_IMAGE_COLORS means free colors allocated for the image, if
1241 any. */
1243 #define CLEAR_IMAGE_PIXMAP (1 << 0)
1244 #define CLEAR_IMAGE_MASK (1 << 1)
1245 #define CLEAR_IMAGE_COLORS (1 << 2)
1247 static void
1248 x_clear_image_1 (struct frame *f, struct image *img, int flags)
1250 if (flags & CLEAR_IMAGE_PIXMAP)
1252 if (img->pixmap)
1254 Free_Pixmap (FRAME_X_DISPLAY (f), img->pixmap);
1255 img->pixmap = NO_PIXMAP;
1256 /* NOTE (HAVE_NS): background color is NOT an indexed color! */
1257 img->background_valid = 0;
1259 #ifdef HAVE_X_WINDOWS
1260 if (img->ximg)
1262 x_destroy_x_image (img->ximg);
1263 img->ximg = NULL;
1264 img->background_valid = 0;
1266 #endif
1269 if (flags & CLEAR_IMAGE_MASK)
1271 if (img->mask)
1273 Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
1274 img->mask = NO_PIXMAP;
1275 img->background_transparent_valid = 0;
1277 #ifdef HAVE_X_WINDOWS
1278 if (img->mask_img)
1280 x_destroy_x_image (img->mask_img);
1281 img->mask_img = NULL;
1282 img->background_transparent_valid = 0;
1284 #endif
1287 if ((flags & CLEAR_IMAGE_COLORS) && img->ncolors)
1289 /* W32_TODO: color table support. */
1290 #ifdef HAVE_X_WINDOWS
1291 x_free_colors (f, img->colors, img->ncolors);
1292 #endif /* HAVE_X_WINDOWS */
1293 xfree (img->colors);
1294 img->colors = NULL;
1295 img->ncolors = 0;
1300 /* Free X resources of image IMG which is used on frame F. */
1302 static void
1303 x_clear_image (struct frame *f, struct image *img)
1305 block_input ();
1306 x_clear_image_1 (f, img,
1307 CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_MASK | CLEAR_IMAGE_COLORS);
1308 unblock_input ();
1312 /* Allocate color COLOR_NAME for image IMG on frame F. If color
1313 cannot be allocated, use DFLT. Add a newly allocated color to
1314 IMG->colors, so that it can be freed again. Value is the pixel
1315 color. */
1317 static unsigned long
1318 x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name,
1319 unsigned long dflt)
1321 XColor color;
1322 unsigned long result;
1324 eassert (STRINGP (color_name));
1326 if (x_defined_color (f, SSDATA (color_name), &color, 1)
1327 && img->ncolors < min (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *img->colors,
1328 INT_MAX))
1330 /* This isn't called frequently so we get away with simply
1331 reallocating the color vector to the needed size, here. */
1332 ptrdiff_t ncolors = img->ncolors + 1;
1333 img->colors = xrealloc (img->colors, ncolors * sizeof *img->colors);
1334 img->colors[ncolors - 1] = color.pixel;
1335 img->ncolors = ncolors;
1336 result = color.pixel;
1338 else
1339 result = dflt;
1341 return result;
1346 /***********************************************************************
1347 Image Cache
1348 ***********************************************************************/
1350 static void cache_image (struct frame *f, struct image *img);
1352 /* Return a new, initialized image cache that is allocated from the
1353 heap. Call free_image_cache to free an image cache. */
1355 struct image_cache *
1356 make_image_cache (void)
1358 struct image_cache *c = xmalloc (sizeof *c);
1360 c->size = 50;
1361 c->used = c->refcount = 0;
1362 c->images = xmalloc (c->size * sizeof *c->images);
1363 c->buckets = xzalloc (IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets);
1364 return c;
1368 /* Find an image matching SPEC in the cache, and return it. If no
1369 image is found, return NULL. */
1370 static struct image *
1371 search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash)
1373 struct image *img;
1374 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1375 int i = hash % IMAGE_CACHE_BUCKETS_SIZE;
1377 if (!c) return NULL;
1379 /* If the image spec does not specify a background color, the cached
1380 image must have the same background color as the current frame.
1381 The foreground color must also match, for the sake of monochrome
1382 images.
1384 In fact, we could ignore the foreground color matching condition
1385 for color images, or if the image spec specifies :foreground;
1386 similarly we could ignore the background color matching condition
1387 for formats that don't use transparency (such as jpeg), or if the
1388 image spec specifies :background. However, the extra memory
1389 usage is probably negligible in practice, so we don't bother. */
1391 for (img = c->buckets[i]; img; img = img->next)
1392 if (img->hash == hash
1393 && !NILP (Fequal (img->spec, spec))
1394 && img->frame_foreground == FRAME_FOREGROUND_PIXEL (f)
1395 && img->frame_background == FRAME_BACKGROUND_PIXEL (f))
1396 break;
1397 return img;
1401 /* Search frame F for an image with spec SPEC, and free it. */
1403 static void
1404 uncache_image (struct frame *f, Lisp_Object spec)
1406 struct image *img = search_image_cache (f, spec, sxhash (spec, 0));
1407 if (img)
1409 free_image (f, img);
1410 /* As display glyphs may still be referring to the image ID, we
1411 must garbage the frame (Bug#6426). */
1412 SET_FRAME_GARBAGED (f);
1417 /* Free image cache of frame F. Be aware that X frames share images
1418 caches. */
1420 void
1421 free_image_cache (struct frame *f)
1423 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1424 if (c)
1426 ptrdiff_t i;
1428 /* Cache should not be referenced by any frame when freed. */
1429 eassert (c->refcount == 0);
1431 for (i = 0; i < c->used; ++i)
1432 free_image (f, c->images[i]);
1433 xfree (c->images);
1434 xfree (c->buckets);
1435 xfree (c);
1436 FRAME_IMAGE_CACHE (f) = NULL;
1441 /* Clear image cache of frame F. FILTER=t means free all images.
1442 FILTER=nil means clear only images that haven't been
1443 displayed for some time.
1444 Else, only free the images which have FILTER in their `dependencies'.
1445 Should be called from time to time to reduce the number of loaded images.
1446 If image-cache-eviction-delay is non-nil, this frees images in the cache
1447 which weren't displayed for at least that many seconds. */
1449 static void
1450 clear_image_cache (struct frame *f, Lisp_Object filter)
1452 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1454 if (c)
1456 ptrdiff_t i, nfreed = 0;
1458 /* Block input so that we won't be interrupted by a SIGIO
1459 while being in an inconsistent state. */
1460 block_input ();
1462 if (!NILP (filter))
1464 /* Filter image cache. */
1465 for (i = 0; i < c->used; ++i)
1467 struct image *img = c->images[i];
1468 if (img && (EQ (Qt, filter)
1469 || !NILP (Fmember (filter, img->dependencies))))
1471 free_image (f, img);
1472 ++nfreed;
1476 else if (INTEGERP (Vimage_cache_eviction_delay))
1478 /* Free cache based on timestamp. */
1479 struct timespec old, t;
1480 double delay;
1481 ptrdiff_t nimages = 0;
1483 for (i = 0; i < c->used; ++i)
1484 if (c->images[i])
1485 nimages++;
1487 /* If the number of cached images has grown unusually large,
1488 decrease the cache eviction delay (Bug#6230). */
1489 delay = XINT (Vimage_cache_eviction_delay);
1490 if (nimages > 40)
1491 delay = 1600 * delay / nimages / nimages;
1492 delay = max (delay, 1);
1494 t = current_timespec ();
1495 old = timespec_sub (t, dtotimespec (delay));
1497 for (i = 0; i < c->used; ++i)
1499 struct image *img = c->images[i];
1500 if (img && timespec_cmp (img->timestamp, old) < 0)
1502 free_image (f, img);
1503 ++nfreed;
1508 /* We may be clearing the image cache because, for example,
1509 Emacs was iconified for a longer period of time. In that
1510 case, current matrices may still contain references to
1511 images freed above. So, clear these matrices. */
1512 if (nfreed)
1514 Lisp_Object tail, frame;
1516 FOR_EACH_FRAME (tail, frame)
1518 struct frame *fr = XFRAME (frame);
1519 if (FRAME_IMAGE_CACHE (fr) == c)
1520 clear_current_matrices (fr);
1523 ++windows_or_buffers_changed;
1526 unblock_input ();
1530 void
1531 clear_image_caches (Lisp_Object filter)
1533 /* FIXME: We want to do
1534 * struct terminal *t;
1535 * for (t = terminal_list; t; t = t->next_terminal)
1536 * clear_image_cache (t, filter); */
1537 Lisp_Object tail, frame;
1538 FOR_EACH_FRAME (tail, frame)
1539 if (FRAME_WINDOW_P (XFRAME (frame)))
1540 clear_image_cache (XFRAME (frame), filter);
1543 DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache,
1544 0, 1, 0,
1545 doc: /* Clear the image cache.
1546 FILTER nil or a frame means clear all images in the selected frame.
1547 FILTER t means clear the image caches of all frames.
1548 Anything else, means only clear those images which refer to FILTER,
1549 which is then usually a filename. */)
1550 (Lisp_Object filter)
1552 if (!(EQ (filter, Qnil) || FRAMEP (filter)))
1553 clear_image_caches (filter);
1554 else
1555 clear_image_cache (decode_window_system_frame (filter), Qt);
1557 return Qnil;
1561 DEFUN ("image-flush", Fimage_flush, Simage_flush,
1562 1, 2, 0,
1563 doc: /* Flush the image with specification SPEC on frame FRAME.
1564 This removes the image from the Emacs image cache. If SPEC specifies
1565 an image file, the next redisplay of this image will read from the
1566 current contents of that file.
1568 FRAME nil or omitted means use the selected frame.
1569 FRAME t means refresh the image on all frames. */)
1570 (Lisp_Object spec, Lisp_Object frame)
1572 if (!valid_image_p (spec))
1573 error ("Invalid image specification");
1575 if (EQ (frame, Qt))
1577 Lisp_Object tail;
1578 FOR_EACH_FRAME (tail, frame)
1580 struct frame *f = XFRAME (frame);
1581 if (FRAME_WINDOW_P (f))
1582 uncache_image (f, spec);
1585 else
1586 uncache_image (decode_window_system_frame (frame), spec);
1588 return Qnil;
1592 /* Compute masks and transform image IMG on frame F, as specified
1593 by the image's specification, */
1595 static void
1596 postprocess_image (struct frame *f, struct image *img)
1598 /* Manipulation of the image's mask. */
1599 if (img->pixmap)
1601 Lisp_Object conversion, spec;
1602 Lisp_Object mask;
1604 spec = img->spec;
1606 /* `:heuristic-mask t'
1607 `:mask heuristic'
1608 means build a mask heuristically.
1609 `:heuristic-mask (R G B)'
1610 `:mask (heuristic (R G B))'
1611 means build a mask from color (R G B) in the
1612 image.
1613 `:mask nil'
1614 means remove a mask, if any. */
1616 mask = image_spec_value (spec, QCheuristic_mask, NULL);
1617 if (!NILP (mask))
1618 x_build_heuristic_mask (f, img, mask);
1619 else
1621 bool found_p;
1623 mask = image_spec_value (spec, QCmask, &found_p);
1625 if (EQ (mask, Qheuristic))
1626 x_build_heuristic_mask (f, img, Qt);
1627 else if (CONSP (mask)
1628 && EQ (XCAR (mask), Qheuristic))
1630 if (CONSP (XCDR (mask)))
1631 x_build_heuristic_mask (f, img, XCAR (XCDR (mask)));
1632 else
1633 x_build_heuristic_mask (f, img, XCDR (mask));
1635 else if (NILP (mask) && found_p && img->mask)
1636 x_clear_image_1 (f, img, CLEAR_IMAGE_MASK);
1640 /* Should we apply an image transformation algorithm? */
1641 conversion = image_spec_value (spec, QCconversion, NULL);
1642 if (EQ (conversion, Qdisabled))
1643 x_disable_image (f, img);
1644 else if (EQ (conversion, Qlaplace))
1645 x_laplace (f, img);
1646 else if (EQ (conversion, Qemboss))
1647 x_emboss (f, img);
1648 else if (CONSP (conversion)
1649 && EQ (XCAR (conversion), Qedge_detection))
1651 Lisp_Object tem;
1652 tem = XCDR (conversion);
1653 if (CONSP (tem))
1654 x_edge_detection (f, img,
1655 Fplist_get (tem, QCmatrix),
1656 Fplist_get (tem, QCcolor_adjustment));
1662 /* Return the id of image with Lisp specification SPEC on frame F.
1663 SPEC must be a valid Lisp image specification (see valid_image_p). */
1665 ptrdiff_t
1666 lookup_image (struct frame *f, Lisp_Object spec)
1668 struct image *img;
1669 EMACS_UINT hash;
1671 /* F must be a window-system frame, and SPEC must be a valid image
1672 specification. */
1673 eassert (FRAME_WINDOW_P (f));
1674 eassert (valid_image_p (spec));
1676 /* Look up SPEC in the hash table of the image cache. */
1677 hash = sxhash (spec, 0);
1678 img = search_image_cache (f, spec, hash);
1679 if (img && img->load_failed_p)
1681 free_image (f, img);
1682 img = NULL;
1685 /* If not found, create a new image and cache it. */
1686 if (img == NULL)
1688 block_input ();
1689 img = make_image (spec, hash);
1690 cache_image (f, img);
1691 img->load_failed_p = ! img->type->load (f, img);
1692 img->frame_foreground = FRAME_FOREGROUND_PIXEL (f);
1693 img->frame_background = FRAME_BACKGROUND_PIXEL (f);
1695 /* If we can't load the image, and we don't have a width and
1696 height, use some arbitrary width and height so that we can
1697 draw a rectangle for it. */
1698 if (img->load_failed_p)
1700 Lisp_Object value;
1702 value = image_spec_value (spec, QCwidth, NULL);
1703 img->width = (INTEGERP (value)
1704 ? XFASTINT (value) : DEFAULT_IMAGE_WIDTH);
1705 value = image_spec_value (spec, QCheight, NULL);
1706 img->height = (INTEGERP (value)
1707 ? XFASTINT (value) : DEFAULT_IMAGE_HEIGHT);
1709 else
1711 /* Handle image type independent image attributes
1712 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
1713 `:background COLOR'. */
1714 Lisp_Object ascent, margin, relief, bg;
1715 int relief_bound;
1717 ascent = image_spec_value (spec, QCascent, NULL);
1718 if (INTEGERP (ascent))
1719 img->ascent = XFASTINT (ascent);
1720 else if (EQ (ascent, Qcenter))
1721 img->ascent = CENTERED_IMAGE_ASCENT;
1723 margin = image_spec_value (spec, QCmargin, NULL);
1724 if (INTEGERP (margin))
1725 img->vmargin = img->hmargin = XFASTINT (margin);
1726 else if (CONSP (margin))
1728 img->hmargin = XFASTINT (XCAR (margin));
1729 img->vmargin = XFASTINT (XCDR (margin));
1732 relief = image_spec_value (spec, QCrelief, NULL);
1733 relief_bound = INT_MAX - max (img->hmargin, img->vmargin);
1734 if (RANGED_INTEGERP (- relief_bound, relief, relief_bound))
1736 img->relief = XINT (relief);
1737 img->hmargin += eabs (img->relief);
1738 img->vmargin += eabs (img->relief);
1741 if (! img->background_valid)
1743 bg = image_spec_value (img->spec, QCbackground, NULL);
1744 if (!NILP (bg))
1746 img->background
1747 = x_alloc_image_color (f, img, bg,
1748 FRAME_BACKGROUND_PIXEL (f));
1749 img->background_valid = 1;
1753 /* Do image transformations and compute masks, unless we
1754 don't have the image yet. */
1755 if (!EQ (*img->type->type, Qpostscript))
1756 postprocess_image (f, img);
1759 unblock_input ();
1762 /* We're using IMG, so set its timestamp to `now'. */
1763 img->timestamp = current_timespec ();
1765 /* Value is the image id. */
1766 return img->id;
1770 /* Cache image IMG in the image cache of frame F. */
1772 static void
1773 cache_image (struct frame *f, struct image *img)
1775 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1776 ptrdiff_t i;
1778 /* Find a free slot in c->images. */
1779 for (i = 0; i < c->used; ++i)
1780 if (c->images[i] == NULL)
1781 break;
1783 /* If no free slot found, maybe enlarge c->images. */
1784 if (i == c->used && c->used == c->size)
1785 c->images = xpalloc (c->images, &c->size, 1, -1, sizeof *c->images);
1787 /* Add IMG to c->images, and assign IMG an id. */
1788 c->images[i] = img;
1789 img->id = i;
1790 if (i == c->used)
1791 ++c->used;
1793 /* Add IMG to the cache's hash table. */
1794 i = img->hash % IMAGE_CACHE_BUCKETS_SIZE;
1795 img->next = c->buckets[i];
1796 if (img->next)
1797 img->next->prev = img;
1798 img->prev = NULL;
1799 c->buckets[i] = img;
1803 /* Call FN on every image in the image cache of frame F. Used to mark
1804 Lisp Objects in the image cache. */
1806 /* Mark Lisp objects in image IMG. */
1808 static void
1809 mark_image (struct image *img)
1811 mark_object (img->spec);
1812 mark_object (img->dependencies);
1814 if (!NILP (img->lisp_data))
1815 mark_object (img->lisp_data);
1819 void
1820 mark_image_cache (struct image_cache *c)
1822 if (c)
1824 ptrdiff_t i;
1825 for (i = 0; i < c->used; ++i)
1826 if (c->images[i])
1827 mark_image (c->images[i]);
1833 /***********************************************************************
1834 X / NS / W32 support code
1835 ***********************************************************************/
1837 #ifdef WINDOWSNT
1839 /* Macro for defining functions that will be loaded from image DLLs. */
1840 #define DEF_IMGLIB_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args
1842 /* Macro for loading those image functions from the library. */
1843 #define LOAD_IMGLIB_FN(lib,func) { \
1844 fn_##func = (void *) GetProcAddress (lib, #func); \
1845 if (!fn_##func) return 0; \
1848 #endif /* WINDOWSNT */
1850 /* Return true if XIMG's size WIDTH x HEIGHT doesn't break the
1851 windowing system.
1852 WIDTH and HEIGHT must both be positive.
1853 If XIMG is null, assume it is a bitmap. */
1854 static bool
1855 x_check_image_size (XImagePtr ximg, int width, int height)
1857 #ifdef HAVE_X_WINDOWS
1858 /* Respect Xlib's limits: it cannot deal with images that have more
1859 than INT_MAX (and/or UINT_MAX) bytes. And respect Emacs's limits
1860 of PTRDIFF_MAX (and/or SIZE_MAX) bytes for any object. */
1861 enum
1863 XLIB_BYTES_MAX = min (INT_MAX, UINT_MAX),
1864 X_IMAGE_BYTES_MAX = min (XLIB_BYTES_MAX, min (PTRDIFF_MAX, SIZE_MAX))
1867 int bitmap_pad, depth, bytes_per_line;
1868 if (ximg)
1870 bitmap_pad = ximg->bitmap_pad;
1871 depth = ximg->depth;
1872 bytes_per_line = ximg->bytes_per_line;
1874 else
1876 bitmap_pad = 8;
1877 depth = 1;
1878 bytes_per_line = (width >> 3) + ((width & 7) != 0);
1880 return (width <= (INT_MAX - (bitmap_pad - 1)) / depth
1881 && height <= X_IMAGE_BYTES_MAX / bytes_per_line);
1882 #else
1883 /* FIXME: Implement this check for the HAVE_NS and HAVE_NTGUI cases.
1884 For now, assume that every image size is allowed on these systems. */
1885 return 1;
1886 #endif
1889 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
1890 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
1891 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
1892 via xmalloc. Print error messages via image_error if an error
1893 occurs. Value is true if successful.
1895 On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
1896 should indicate the bit depth of the image. */
1898 static bool
1899 x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
1900 XImagePtr *ximg, Pixmap *pixmap)
1902 #ifdef HAVE_X_WINDOWS
1903 Display *display = FRAME_X_DISPLAY (f);
1904 Window window = FRAME_X_WINDOW (f);
1905 Screen *screen = FRAME_X_SCREEN (f);
1907 eassert (input_blocked_p ());
1909 if (depth <= 0)
1910 depth = DefaultDepthOfScreen (screen);
1911 *ximg = XCreateImage (display, DefaultVisualOfScreen (screen),
1912 depth, ZPixmap, 0, NULL, width, height,
1913 depth > 16 ? 32 : depth > 8 ? 16 : 8, 0);
1914 if (*ximg == NULL)
1916 image_error ("Unable to allocate X image", Qnil, Qnil);
1917 return 0;
1920 if (! x_check_image_size (*ximg, width, height))
1922 x_destroy_x_image (*ximg);
1923 *ximg = NULL;
1924 image_error ("Image too large (%dx%d)",
1925 make_number (width), make_number (height));
1926 return 0;
1929 /* Allocate image raster. */
1930 (*ximg)->data = xmalloc ((*ximg)->bytes_per_line * height);
1932 /* Allocate a pixmap of the same size. */
1933 *pixmap = XCreatePixmap (display, window, width, height, depth);
1934 if (*pixmap == NO_PIXMAP)
1936 x_destroy_x_image (*ximg);
1937 *ximg = NULL;
1938 image_error ("Unable to create X pixmap", Qnil, Qnil);
1939 return 0;
1942 return 1;
1943 #endif /* HAVE_X_WINDOWS */
1945 #ifdef HAVE_NTGUI
1947 BITMAPINFOHEADER *header;
1948 HDC hdc;
1949 int scanline_width_bits;
1950 int remainder;
1951 int palette_colors = 0;
1953 if (depth == 0)
1954 depth = 24;
1956 if (depth != 1 && depth != 4 && depth != 8
1957 && depth != 16 && depth != 24 && depth != 32)
1959 image_error ("Invalid image bit depth specified", Qnil, Qnil);
1960 return 0;
1963 scanline_width_bits = width * depth;
1964 remainder = scanline_width_bits % 32;
1966 if (remainder)
1967 scanline_width_bits += 32 - remainder;
1969 /* Bitmaps with a depth less than 16 need a palette. */
1970 /* BITMAPINFO structure already contains the first RGBQUAD. */
1971 if (depth < 16)
1972 palette_colors = 1 << (depth - 1);
1974 *ximg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD));
1976 header = &(*ximg)->info.bmiHeader;
1977 memset (&(*ximg)->info, 0, sizeof (BITMAPINFO));
1978 header->biSize = sizeof (*header);
1979 header->biWidth = width;
1980 header->biHeight = -height; /* negative indicates a top-down bitmap. */
1981 header->biPlanes = 1;
1982 header->biBitCount = depth;
1983 header->biCompression = BI_RGB;
1984 header->biClrUsed = palette_colors;
1986 /* TODO: fill in palette. */
1987 if (depth == 1)
1989 (*ximg)->info.bmiColors[0].rgbBlue = 0;
1990 (*ximg)->info.bmiColors[0].rgbGreen = 0;
1991 (*ximg)->info.bmiColors[0].rgbRed = 0;
1992 (*ximg)->info.bmiColors[0].rgbReserved = 0;
1993 (*ximg)->info.bmiColors[1].rgbBlue = 255;
1994 (*ximg)->info.bmiColors[1].rgbGreen = 255;
1995 (*ximg)->info.bmiColors[1].rgbRed = 255;
1996 (*ximg)->info.bmiColors[1].rgbReserved = 0;
1999 hdc = get_frame_dc (f);
2001 /* Create a DIBSection and raster array for the bitmap,
2002 and store its handle in *pixmap. */
2003 *pixmap = CreateDIBSection (hdc, &((*ximg)->info),
2004 (depth < 16) ? DIB_PAL_COLORS : DIB_RGB_COLORS,
2005 /* casting avoids a GCC warning */
2006 (void **)&((*ximg)->data), NULL, 0);
2008 /* Realize display palette and garbage all frames. */
2009 release_frame_dc (f, hdc);
2011 if (*pixmap == NULL)
2013 DWORD err = GetLastError ();
2014 Lisp_Object errcode;
2015 /* All system errors are < 10000, so the following is safe. */
2016 XSETINT (errcode, err);
2017 image_error ("Unable to create bitmap, error code %d", errcode, Qnil);
2018 x_destroy_x_image (*ximg);
2019 return 0;
2022 return 1;
2024 #endif /* HAVE_NTGUI */
2026 #ifdef HAVE_NS
2027 *pixmap = ns_image_for_XPM (width, height, depth);
2028 if (*pixmap == 0)
2030 *ximg = NULL;
2031 image_error ("Unable to allocate NSImage for XPM pixmap", Qnil, Qnil);
2032 return 0;
2034 *ximg = *pixmap;
2035 return 1;
2036 #endif
2040 /* Destroy XImage XIMG. Free XIMG->data. */
2042 static void
2043 x_destroy_x_image (XImagePtr ximg)
2045 eassert (input_blocked_p ());
2046 if (ximg)
2048 #ifdef HAVE_X_WINDOWS
2049 xfree (ximg->data);
2050 ximg->data = NULL;
2051 XDestroyImage (ximg);
2052 #endif /* HAVE_X_WINDOWS */
2053 #ifdef HAVE_NTGUI
2054 /* Data will be freed by DestroyObject. */
2055 ximg->data = NULL;
2056 xfree (ximg);
2057 #endif /* HAVE_NTGUI */
2058 #ifdef HAVE_NS
2059 ns_release_object (ximg);
2060 #endif /* HAVE_NS */
2065 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
2066 are width and height of both the image and pixmap. */
2068 static void
2069 x_put_x_image (struct frame *f, XImagePtr ximg, Pixmap pixmap, int width, int height)
2071 #ifdef HAVE_X_WINDOWS
2072 GC gc;
2074 eassert (input_blocked_p ());
2075 gc = XCreateGC (FRAME_X_DISPLAY (f), pixmap, 0, NULL);
2076 XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, ximg, 0, 0, 0, 0, width, height);
2077 XFreeGC (FRAME_X_DISPLAY (f), gc);
2078 #endif /* HAVE_X_WINDOWS */
2080 #ifdef HAVE_NTGUI
2081 #if 0 /* I don't think this is necessary looking at where it is used. */
2082 HDC hdc = get_frame_dc (f);
2083 SetDIBits (hdc, pixmap, 0, height, ximg->data, &(ximg->info), DIB_RGB_COLORS);
2084 release_frame_dc (f, hdc);
2085 #endif
2086 #endif /* HAVE_NTGUI */
2088 #ifdef HAVE_NS
2089 eassert (ximg == pixmap);
2090 ns_retain_object (ximg);
2091 #endif
2094 /* Thin wrapper for x_create_x_image_and_pixmap, so that it matches
2095 with image_put_x_image. */
2097 static bool
2098 image_create_x_image_and_pixmap (struct frame *f, struct image *img,
2099 int width, int height, int depth,
2100 XImagePtr *ximg, bool mask_p)
2102 eassert ((!mask_p ? img->pixmap : img->mask) == NO_PIXMAP);
2104 return x_create_x_image_and_pixmap (f, width, height, depth, ximg,
2105 !mask_p ? &img->pixmap : &img->mask);
2108 /* Put X image XIMG into image IMG on frame F, as a mask if and only
2109 if MASK_P. On X, this simply records XIMG on a member of IMG, so
2110 it can be put into the pixmap afterwards via image_sync_to_pixmaps.
2111 On the other platforms, it puts XIMG into the pixmap, then frees
2112 the X image and its buffer. */
2114 static void
2115 image_put_x_image (struct frame *f, struct image *img, XImagePtr ximg,
2116 bool mask_p)
2118 #ifdef HAVE_X_WINDOWS
2119 if (!mask_p)
2121 eassert (img->ximg == NULL);
2122 img->ximg = ximg;
2124 else
2126 eassert (img->mask_img == NULL);
2127 img->mask_img = ximg;
2129 #else
2130 x_put_x_image (f, ximg, !mask_p ? img->pixmap : img->mask,
2131 img->width, img->height);
2132 x_destroy_x_image (ximg);
2133 #endif
2136 #ifdef HAVE_X_WINDOWS
2137 /* Put the X images recorded in IMG on frame F into pixmaps, then free
2138 the X images and their buffers. */
2140 static void
2141 image_sync_to_pixmaps (struct frame *f, struct image *img)
2143 if (img->ximg)
2145 x_put_x_image (f, img->ximg, img->pixmap, img->width, img->height);
2146 x_destroy_x_image (img->ximg);
2147 img->ximg = NULL;
2149 if (img->mask_img)
2151 x_put_x_image (f, img->mask_img, img->mask, img->width, img->height);
2152 x_destroy_x_image (img->mask_img);
2153 img->mask_img = NULL;
2156 #endif
2158 #ifdef HAVE_NTGUI
2159 /* Create a memory device context for IMG on frame F. It stores the
2160 currently selected GDI object into *PREV for future restoration by
2161 image_unget_x_image_or_dc. */
2163 static XImagePtr_or_DC
2164 image_get_x_image_or_dc (struct frame *f, struct image *img, bool mask_p,
2165 HGDIOBJ *prev)
2167 HDC frame_dc = get_frame_dc (f);
2168 XImagePtr_or_DC ximg = CreateCompatibleDC (frame_dc);
2170 release_frame_dc (f, frame_dc);
2171 *prev = SelectObject (ximg, !mask_p ? img->pixmap : img->mask);
2173 return ximg;
2176 static void
2177 image_unget_x_image_or_dc (struct image *img, bool mask_p,
2178 XImagePtr_or_DC ximg, HGDIOBJ prev)
2180 SelectObject (ximg, prev);
2181 DeleteDC (ximg);
2183 #else /* !HAVE_NTGUI */
2184 /* Get the X image for IMG on frame F. The resulting X image data
2185 should be treated as read-only at least on X. */
2187 static XImagePtr
2188 image_get_x_image (struct frame *f, struct image *img, bool mask_p)
2190 #ifdef HAVE_X_WINDOWS
2191 XImagePtr ximg_in_img = !mask_p ? img->ximg : img->mask_img;
2193 if (ximg_in_img)
2194 return ximg_in_img;
2195 else
2196 return XGetImage (FRAME_X_DISPLAY (f), !mask_p ? img->pixmap : img->mask,
2197 0, 0, img->width, img->height, ~0, ZPixmap);
2198 #elif defined (HAVE_NS)
2199 XImagePtr pixmap = !mask_p ? img->pixmap : img->mask;
2201 ns_retain_object (pixmap);
2202 return pixmap;
2203 #endif
2206 static void
2207 image_unget_x_image (struct image *img, bool mask_p, XImagePtr ximg)
2209 #ifdef HAVE_X_WINDOWS
2210 XImagePtr ximg_in_img = !mask_p ? img->ximg : img->mask_img;
2212 if (ximg_in_img)
2213 eassert (ximg == ximg_in_img);
2214 else
2215 XDestroyImage (ximg);
2216 #elif defined (HAVE_NS)
2217 ns_release_object (ximg);
2218 #endif
2220 #endif /* !HAVE_NTGUI */
2223 /***********************************************************************
2224 File Handling
2225 ***********************************************************************/
2227 /* Find image file FILE. Look in data-directory/images, then
2228 x-bitmap-file-path. Value is the encoded full name of the file
2229 found, or nil if not found. */
2231 Lisp_Object
2232 x_find_image_file (Lisp_Object file)
2234 Lisp_Object file_found, search_path;
2235 int fd;
2237 /* TODO I think this should use something like image-load-path
2238 instead. Unfortunately, that can contain non-string elements. */
2239 search_path = Fcons (Fexpand_file_name (build_string ("images"),
2240 Vdata_directory),
2241 Vx_bitmap_file_path);
2243 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
2244 fd = openp (search_path, file, Qnil, &file_found, Qnil);
2246 if (fd == -1)
2247 file_found = Qnil;
2248 else
2250 file_found = ENCODE_FILE (file_found);
2251 if (fd != -2)
2252 emacs_close (fd);
2255 return file_found;
2259 /* Read FILE into memory. Value is a pointer to a buffer allocated
2260 with xmalloc holding FILE's contents. Value is null if an error
2261 occurred. *SIZE is set to the size of the file. */
2263 static unsigned char *
2264 slurp_file (char *file, ptrdiff_t *size)
2266 FILE *fp = emacs_fopen (file, "rb");
2267 unsigned char *buf = NULL;
2268 struct stat st;
2270 if (fp)
2272 ptrdiff_t count = SPECPDL_INDEX ();
2273 record_unwind_protect_ptr (fclose_unwind, fp);
2275 if (fstat (fileno (fp), &st) == 0
2276 && 0 <= st.st_size && st.st_size < min (PTRDIFF_MAX, SIZE_MAX))
2278 /* Report an error if we read past the purported EOF.
2279 This can happen if the file grows as we read it. */
2280 ptrdiff_t buflen = st.st_size;
2281 buf = xmalloc (buflen + 1);
2282 if (fread (buf, 1, buflen + 1, fp) == buflen)
2283 *size = buflen;
2284 else
2286 xfree (buf);
2287 buf = NULL;
2291 unbind_to (count, Qnil);
2294 return buf;
2299 /***********************************************************************
2300 XBM images
2301 ***********************************************************************/
2303 static bool xbm_load (struct frame *f, struct image *img);
2304 static bool xbm_image_p (Lisp_Object object);
2305 static bool xbm_file_p (Lisp_Object);
2308 /* Indices of image specification fields in xbm_format, below. */
2310 enum xbm_keyword_index
2312 XBM_TYPE,
2313 XBM_FILE,
2314 XBM_WIDTH,
2315 XBM_HEIGHT,
2316 XBM_DATA,
2317 XBM_FOREGROUND,
2318 XBM_BACKGROUND,
2319 XBM_ASCENT,
2320 XBM_MARGIN,
2321 XBM_RELIEF,
2322 XBM_ALGORITHM,
2323 XBM_HEURISTIC_MASK,
2324 XBM_MASK,
2325 XBM_LAST
2328 /* Vector of image_keyword structures describing the format
2329 of valid XBM image specifications. */
2331 static const struct image_keyword xbm_format[XBM_LAST] =
2333 {":type", IMAGE_SYMBOL_VALUE, 1},
2334 {":file", IMAGE_STRING_VALUE, 0},
2335 {":width", IMAGE_POSITIVE_INTEGER_VALUE, 0},
2336 {":height", IMAGE_POSITIVE_INTEGER_VALUE, 0},
2337 {":data", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
2338 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
2339 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
2340 {":ascent", IMAGE_ASCENT_VALUE, 0},
2341 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
2342 {":relief", IMAGE_INTEGER_VALUE, 0},
2343 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
2344 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
2345 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
2348 /* Structure describing the image type XBM. */
2350 static struct image_type xbm_type =
2352 &Qxbm,
2353 xbm_image_p,
2354 xbm_load,
2355 x_clear_image,
2356 NULL,
2357 NULL
2360 /* Tokens returned from xbm_scan. */
2362 enum xbm_token
2364 XBM_TK_IDENT = 256,
2365 XBM_TK_NUMBER
2369 /* Return true if OBJECT is a valid XBM-type image specification.
2370 A valid specification is a list starting with the symbol `image'
2371 The rest of the list is a property list which must contain an
2372 entry `:type xbm'.
2374 If the specification specifies a file to load, it must contain
2375 an entry `:file FILENAME' where FILENAME is a string.
2377 If the specification is for a bitmap loaded from memory it must
2378 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
2379 WIDTH and HEIGHT are integers > 0. DATA may be:
2381 1. a string large enough to hold the bitmap data, i.e. it must
2382 have a size >= (WIDTH + 7) / 8 * HEIGHT
2384 2. a bool-vector of size >= WIDTH * HEIGHT
2386 3. a vector of strings or bool-vectors, one for each line of the
2387 bitmap.
2389 4. a string containing an in-memory XBM file. WIDTH and HEIGHT
2390 may not be specified in this case because they are defined in the
2391 XBM file.
2393 Both the file and data forms may contain the additional entries
2394 `:background COLOR' and `:foreground COLOR'. If not present,
2395 foreground and background of the frame on which the image is
2396 displayed is used. */
2398 static bool
2399 xbm_image_p (Lisp_Object object)
2401 struct image_keyword kw[XBM_LAST];
2403 memcpy (kw, xbm_format, sizeof kw);
2404 if (!parse_image_spec (object, kw, XBM_LAST, Qxbm))
2405 return 0;
2407 eassert (EQ (kw[XBM_TYPE].value, Qxbm));
2409 if (kw[XBM_FILE].count)
2411 if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_DATA].count)
2412 return 0;
2414 else if (kw[XBM_DATA].count && xbm_file_p (kw[XBM_DATA].value))
2416 /* In-memory XBM file. */
2417 if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_FILE].count)
2418 return 0;
2420 else
2422 Lisp_Object data;
2423 int width, height;
2425 /* Entries for `:width', `:height' and `:data' must be present. */
2426 if (!kw[XBM_WIDTH].count
2427 || !kw[XBM_HEIGHT].count
2428 || !kw[XBM_DATA].count)
2429 return 0;
2431 data = kw[XBM_DATA].value;
2432 width = XFASTINT (kw[XBM_WIDTH].value);
2433 height = XFASTINT (kw[XBM_HEIGHT].value);
2435 /* Check type of data, and width and height against contents of
2436 data. */
2437 if (VECTORP (data))
2439 EMACS_INT i;
2441 /* Number of elements of the vector must be >= height. */
2442 if (ASIZE (data) < height)
2443 return 0;
2445 /* Each string or bool-vector in data must be large enough
2446 for one line of the image. */
2447 for (i = 0; i < height; ++i)
2449 Lisp_Object elt = AREF (data, i);
2451 if (STRINGP (elt))
2453 if (SCHARS (elt)
2454 < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR)
2455 return 0;
2457 else if (BOOL_VECTOR_P (elt))
2459 if (bool_vector_size (elt) < width)
2460 return 0;
2462 else
2463 return 0;
2466 else if (STRINGP (data))
2468 if (SCHARS (data)
2469 < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR * height)
2470 return 0;
2472 else if (BOOL_VECTOR_P (data))
2474 if (bool_vector_size (data) / height < width)
2475 return 0;
2477 else
2478 return 0;
2481 return 1;
2485 /* Scan a bitmap file. FP is the stream to read from. Value is
2486 either an enumerator from enum xbm_token, or a character for a
2487 single-character token, or 0 at end of file. If scanning an
2488 identifier, store the lexeme of the identifier in SVAL. If
2489 scanning a number, store its value in *IVAL. */
2491 static int
2492 xbm_scan (unsigned char **s, unsigned char *end, char *sval, int *ival)
2494 unsigned int c;
2496 loop:
2498 /* Skip white space. */
2499 while (*s < end && (c = *(*s)++, c_isspace (c)))
2502 if (*s >= end)
2503 c = 0;
2504 else if (c_isdigit (c))
2506 int value = 0, digit;
2508 if (c == '0' && *s < end)
2510 c = *(*s)++;
2511 if (c == 'x' || c == 'X')
2513 while (*s < end)
2515 c = *(*s)++;
2516 if (c_isdigit (c))
2517 digit = c - '0';
2518 else if (c >= 'a' && c <= 'f')
2519 digit = c - 'a' + 10;
2520 else if (c >= 'A' && c <= 'F')
2521 digit = c - 'A' + 10;
2522 else
2523 break;
2524 value = 16 * value + digit;
2527 else if (c_isdigit (c))
2529 value = c - '0';
2530 while (*s < end
2531 && (c = *(*s)++, c_isdigit (c)))
2532 value = 8 * value + c - '0';
2535 else
2537 value = c - '0';
2538 while (*s < end
2539 && (c = *(*s)++, c_isdigit (c)))
2540 value = 10 * value + c - '0';
2543 if (*s < end)
2544 *s = *s - 1;
2545 *ival = value;
2546 c = XBM_TK_NUMBER;
2548 else if (c_isalpha (c) || c == '_')
2550 *sval++ = c;
2551 while (*s < end
2552 && (c = *(*s)++, (c_isalnum (c) || c == '_')))
2553 *sval++ = c;
2554 *sval = 0;
2555 if (*s < end)
2556 *s = *s - 1;
2557 c = XBM_TK_IDENT;
2559 else if (c == '/' && **s == '*')
2561 /* C-style comment. */
2562 ++*s;
2563 while (**s && (**s != '*' || *(*s + 1) != '/'))
2564 ++*s;
2565 if (**s)
2567 *s += 2;
2568 goto loop;
2572 return c;
2575 #ifdef HAVE_NTGUI
2577 /* Create a Windows bitmap from X bitmap data. */
2578 static HBITMAP
2579 w32_create_pixmap_from_bitmap_data (int width, int height, char *data)
2581 static unsigned char swap_nibble[16]
2582 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
2583 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
2584 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
2585 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
2586 int i, j, w1, w2;
2587 unsigned char *bits, *p;
2588 HBITMAP bmp;
2590 w1 = (width + 7) / 8; /* nb of 8bits elt in X bitmap */
2591 w2 = ((width + 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
2592 bits = alloca (height * w2);
2593 memset (bits, 0, height * w2);
2594 for (i = 0; i < height; i++)
2596 p = bits + i*w2;
2597 for (j = 0; j < w1; j++)
2599 /* Bitswap XBM bytes to match how Windows does things. */
2600 unsigned char c = *data++;
2601 *p++ = (unsigned char)((swap_nibble[c & 0xf] << 4)
2602 | (swap_nibble[(c>>4) & 0xf]));
2605 bmp = CreateBitmap (width, height, 1, 1, (char *) bits);
2607 return bmp;
2610 static void
2611 convert_mono_to_color_image (struct frame *f, struct image *img,
2612 COLORREF foreground, COLORREF background)
2614 HDC hdc, old_img_dc, new_img_dc;
2615 HGDIOBJ old_prev, new_prev;
2616 HBITMAP new_pixmap;
2618 hdc = get_frame_dc (f);
2619 old_img_dc = CreateCompatibleDC (hdc);
2620 new_img_dc = CreateCompatibleDC (hdc);
2621 new_pixmap = CreateCompatibleBitmap (hdc, img->width, img->height);
2622 release_frame_dc (f, hdc);
2623 old_prev = SelectObject (old_img_dc, img->pixmap);
2624 new_prev = SelectObject (new_img_dc, new_pixmap);
2625 /* Windows convention for mono bitmaps is black = background,
2626 white = foreground. */
2627 SetTextColor (new_img_dc, background);
2628 SetBkColor (new_img_dc, foreground);
2630 BitBlt (new_img_dc, 0, 0, img->width, img->height, old_img_dc,
2631 0, 0, SRCCOPY);
2633 SelectObject (old_img_dc, old_prev);
2634 SelectObject (new_img_dc, new_prev);
2635 DeleteDC (old_img_dc);
2636 DeleteDC (new_img_dc);
2637 DeleteObject (img->pixmap);
2638 if (new_pixmap == 0)
2639 fprintf (stderr, "Failed to convert image to color.\n");
2640 else
2641 img->pixmap = new_pixmap;
2644 #define XBM_BIT_SHUFFLE(b) (~(b))
2646 #else
2648 #define XBM_BIT_SHUFFLE(b) (b)
2650 #endif /* HAVE_NTGUI */
2653 static void
2654 Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data,
2655 RGB_PIXEL_COLOR fg, RGB_PIXEL_COLOR bg,
2656 bool non_default_colors)
2658 #ifdef HAVE_NTGUI
2659 img->pixmap
2660 = w32_create_pixmap_from_bitmap_data (img->width, img->height, data);
2662 /* If colors were specified, transfer the bitmap to a color one. */
2663 if (non_default_colors)
2664 convert_mono_to_color_image (f, img, fg, bg);
2666 #elif defined (HAVE_NS)
2667 img->pixmap = ns_image_from_XBM (data, img->width, img->height);
2669 #else
2670 img->pixmap =
2671 (x_check_image_size (0, img->width, img->height)
2672 ? XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
2673 FRAME_X_WINDOW (f),
2674 data,
2675 img->width, img->height,
2676 fg, bg,
2677 DefaultDepthOfScreen (FRAME_X_SCREEN (f)))
2678 : NO_PIXMAP);
2679 #endif /* !HAVE_NTGUI && !HAVE_NS */
2684 /* Replacement for XReadBitmapFileData which isn't available under old
2685 X versions. CONTENTS is a pointer to a buffer to parse; END is the
2686 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
2687 the image. Return in *DATA the bitmap data allocated with xmalloc.
2688 Value is true if successful. DATA null means just test if
2689 CONTENTS looks like an in-memory XBM file. If INHIBIT_IMAGE_ERROR,
2690 inhibit the call to image_error when the image size is invalid (the
2691 bitmap remains unread). */
2693 static bool
2694 xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *end,
2695 int *width, int *height, char **data,
2696 bool inhibit_image_error)
2698 unsigned char *s = contents;
2699 char buffer[BUFSIZ];
2700 bool padding_p = 0;
2701 bool v10 = 0;
2702 int bytes_per_line, i, nbytes;
2703 char *p;
2704 int value;
2705 int LA1;
2707 #define match() \
2708 LA1 = xbm_scan (&s, end, buffer, &value)
2710 #define expect(TOKEN) \
2711 do \
2713 if (LA1 != (TOKEN)) \
2714 goto failure; \
2715 match (); \
2717 while (0)
2719 #define expect_ident(IDENT) \
2720 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
2721 match (); \
2722 else \
2723 goto failure
2725 *width = *height = -1;
2726 if (data)
2727 *data = NULL;
2728 LA1 = xbm_scan (&s, end, buffer, &value);
2730 /* Parse defines for width, height and hot-spots. */
2731 while (LA1 == '#')
2733 match ();
2734 expect_ident ("define");
2735 expect (XBM_TK_IDENT);
2737 if (LA1 == XBM_TK_NUMBER)
2739 char *q = strrchr (buffer, '_');
2740 q = q ? q + 1 : buffer;
2741 if (strcmp (q, "width") == 0)
2742 *width = value;
2743 else if (strcmp (q, "height") == 0)
2744 *height = value;
2746 expect (XBM_TK_NUMBER);
2749 if (!check_image_size (f, *width, *height))
2751 if (!inhibit_image_error)
2752 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
2753 goto failure;
2755 else if (data == NULL)
2756 goto success;
2758 /* Parse bits. Must start with `static'. */
2759 expect_ident ("static");
2760 if (LA1 == XBM_TK_IDENT)
2762 if (strcmp (buffer, "unsigned") == 0)
2764 match ();
2765 expect_ident ("char");
2767 else if (strcmp (buffer, "short") == 0)
2769 match ();
2770 v10 = 1;
2771 if (*width % 16 && *width % 16 < 9)
2772 padding_p = 1;
2774 else if (strcmp (buffer, "char") == 0)
2775 match ();
2776 else
2777 goto failure;
2779 else
2780 goto failure;
2782 expect (XBM_TK_IDENT);
2783 expect ('[');
2784 expect (']');
2785 expect ('=');
2786 expect ('{');
2788 if (! x_check_image_size (0, *width, *height))
2790 if (!inhibit_image_error)
2791 image_error ("Image too large (%dx%d)",
2792 make_number (*width), make_number (*height));
2793 goto failure;
2795 bytes_per_line = (*width + 7) / 8 + padding_p;
2796 nbytes = bytes_per_line * *height;
2797 p = *data = xmalloc (nbytes);
2799 if (v10)
2801 for (i = 0; i < nbytes; i += 2)
2803 int val = value;
2804 expect (XBM_TK_NUMBER);
2806 *p++ = XBM_BIT_SHUFFLE (val);
2807 if (!padding_p || ((i + 2) % bytes_per_line))
2808 *p++ = XBM_BIT_SHUFFLE (value >> 8);
2810 if (LA1 == ',' || LA1 == '}')
2811 match ();
2812 else
2813 goto failure;
2816 else
2818 for (i = 0; i < nbytes; ++i)
2820 int val = value;
2821 expect (XBM_TK_NUMBER);
2823 *p++ = XBM_BIT_SHUFFLE (val);
2825 if (LA1 == ',' || LA1 == '}')
2826 match ();
2827 else
2828 goto failure;
2832 success:
2833 return 1;
2835 failure:
2837 if (data && *data)
2839 xfree (*data);
2840 *data = NULL;
2842 return 0;
2844 #undef match
2845 #undef expect
2846 #undef expect_ident
2850 /* Load XBM image IMG which will be displayed on frame F from buffer
2851 CONTENTS. END is the end of the buffer. Value is true if
2852 successful. */
2854 static bool
2855 xbm_load_image (struct frame *f, struct image *img, unsigned char *contents,
2856 unsigned char *end)
2858 bool rc;
2859 char *data;
2860 bool success_p = 0;
2862 rc = xbm_read_bitmap_data (f, contents, end, &img->width, &img->height,
2863 &data, 0);
2864 if (rc)
2866 unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
2867 unsigned long background = FRAME_BACKGROUND_PIXEL (f);
2868 bool non_default_colors = 0;
2869 Lisp_Object value;
2871 eassert (img->width > 0 && img->height > 0);
2873 /* Get foreground and background colors, maybe allocate colors. */
2874 value = image_spec_value (img->spec, QCforeground, NULL);
2875 if (!NILP (value))
2877 foreground = x_alloc_image_color (f, img, value, foreground);
2878 non_default_colors = 1;
2880 value = image_spec_value (img->spec, QCbackground, NULL);
2881 if (!NILP (value))
2883 background = x_alloc_image_color (f, img, value, background);
2884 img->background = background;
2885 img->background_valid = 1;
2886 non_default_colors = 1;
2889 Create_Pixmap_From_Bitmap_Data (f, img, data,
2890 foreground, background,
2891 non_default_colors);
2892 xfree (data);
2894 if (img->pixmap == NO_PIXMAP)
2896 x_clear_image (f, img);
2897 image_error ("Unable to create X pixmap for `%s'", img->spec, Qnil);
2899 else
2900 success_p = 1;
2902 else
2903 image_error ("Error loading XBM image `%s'", img->spec, Qnil);
2905 return success_p;
2909 /* Value is true if DATA looks like an in-memory XBM file. */
2911 static bool
2912 xbm_file_p (Lisp_Object data)
2914 int w, h;
2915 return (STRINGP (data)
2916 && xbm_read_bitmap_data (NULL, SDATA (data),
2917 (SDATA (data) + SBYTES (data)),
2918 &w, &h, NULL, 1));
2922 /* Fill image IMG which is used on frame F with pixmap data. Value is
2923 true if successful. */
2925 static bool
2926 xbm_load (struct frame *f, struct image *img)
2928 bool success_p = 0;
2929 Lisp_Object file_name;
2931 eassert (xbm_image_p (img->spec));
2933 /* If IMG->spec specifies a file name, create a non-file spec from it. */
2934 file_name = image_spec_value (img->spec, QCfile, NULL);
2935 if (STRINGP (file_name))
2937 Lisp_Object file;
2938 unsigned char *contents;
2939 ptrdiff_t size;
2941 file = x_find_image_file (file_name);
2942 if (!STRINGP (file))
2944 image_error ("Cannot find image file `%s'", file_name, Qnil);
2945 return 0;
2948 contents = slurp_file (SSDATA (file), &size);
2949 if (contents == NULL)
2951 image_error ("Error loading XBM image `%s'", img->spec, Qnil);
2952 return 0;
2955 success_p = xbm_load_image (f, img, contents, contents + size);
2956 xfree (contents);
2958 else
2960 struct image_keyword fmt[XBM_LAST];
2961 Lisp_Object data;
2962 unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
2963 unsigned long background = FRAME_BACKGROUND_PIXEL (f);
2964 bool non_default_colors = 0;
2965 char *bits;
2966 bool parsed_p;
2967 bool in_memory_file_p = 0;
2969 /* See if data looks like an in-memory XBM file. */
2970 data = image_spec_value (img->spec, QCdata, NULL);
2971 in_memory_file_p = xbm_file_p (data);
2973 /* Parse the image specification. */
2974 memcpy (fmt, xbm_format, sizeof fmt);
2975 parsed_p = parse_image_spec (img->spec, fmt, XBM_LAST, Qxbm);
2976 eassert (parsed_p);
2978 /* Get specified width, and height. */
2979 if (!in_memory_file_p)
2981 img->width = XFASTINT (fmt[XBM_WIDTH].value);
2982 img->height = XFASTINT (fmt[XBM_HEIGHT].value);
2983 eassert (img->width > 0 && img->height > 0);
2984 if (!check_image_size (f, img->width, img->height))
2986 image_error ("Invalid image size (see `max-image-size')",
2987 Qnil, Qnil);
2988 return 0;
2992 /* Get foreground and background colors, maybe allocate colors. */
2993 if (fmt[XBM_FOREGROUND].count
2994 && STRINGP (fmt[XBM_FOREGROUND].value))
2996 foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value,
2997 foreground);
2998 non_default_colors = 1;
3001 if (fmt[XBM_BACKGROUND].count
3002 && STRINGP (fmt[XBM_BACKGROUND].value))
3004 background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value,
3005 background);
3006 non_default_colors = 1;
3009 if (in_memory_file_p)
3010 success_p = xbm_load_image (f, img, SDATA (data),
3011 (SDATA (data)
3012 + SBYTES (data)));
3013 else
3015 if (VECTORP (data))
3017 int i;
3018 char *p;
3019 int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
3021 p = bits = alloca (nbytes * img->height);
3022 for (i = 0; i < img->height; ++i, p += nbytes)
3024 Lisp_Object line = AREF (data, i);
3025 if (STRINGP (line))
3026 memcpy (p, SDATA (line), nbytes);
3027 else
3028 memcpy (p, XBOOL_VECTOR (line)->data, nbytes);
3031 else if (STRINGP (data))
3032 bits = SSDATA (data);
3033 else
3034 bits = (char *) XBOOL_VECTOR (data)->data;
3036 #ifdef HAVE_NTGUI
3038 char *invertedBits;
3039 int nbytes, i;
3040 /* Windows mono bitmaps are reversed compared with X. */
3041 invertedBits = bits;
3042 nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR
3043 * img->height;
3044 bits = alloca (nbytes);
3045 for (i = 0; i < nbytes; i++)
3046 bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]);
3048 #endif
3049 /* Create the pixmap. */
3051 if (x_check_image_size (0, img->width, img->height))
3052 Create_Pixmap_From_Bitmap_Data (f, img, bits,
3053 foreground, background,
3054 non_default_colors);
3055 else
3056 img->pixmap = NO_PIXMAP;
3058 if (img->pixmap)
3059 success_p = 1;
3060 else
3062 image_error ("Unable to create pixmap for XBM image `%s'",
3063 img->spec, Qnil);
3064 x_clear_image (f, img);
3069 return success_p;
3074 /***********************************************************************
3075 XPM images
3076 ***********************************************************************/
3078 #if defined (HAVE_XPM) || defined (HAVE_NS)
3080 static bool xpm_image_p (Lisp_Object object);
3081 static bool xpm_load (struct frame *f, struct image *img);
3083 #endif /* HAVE_XPM || HAVE_NS */
3085 #ifdef HAVE_XPM
3086 #ifdef HAVE_NTGUI
3087 /* Indicate to xpm.h that we don't have Xlib. */
3088 #define FOR_MSW
3089 /* simx.h in xpm defines XColor and XImage differently than Emacs. */
3090 /* It also defines Display the same way as Emacs, but gcc 3.3 still barfs. */
3091 #define XColor xpm_XColor
3092 #define XImage xpm_XImage
3093 #define Display xpm_Display
3094 #define PIXEL_ALREADY_TYPEDEFED
3095 #include "X11/xpm.h"
3096 #undef FOR_MSW
3097 #undef XColor
3098 #undef XImage
3099 #undef Display
3100 #undef PIXEL_ALREADY_TYPEDEFED
3101 #else
3102 #include "X11/xpm.h"
3103 #endif /* HAVE_NTGUI */
3104 #endif /* HAVE_XPM */
3106 #if defined (HAVE_XPM) || defined (HAVE_NS)
3107 /* The symbol `xpm' identifying XPM-format images. */
3109 static Lisp_Object Qxpm;
3111 /* Indices of image specification fields in xpm_format, below. */
3113 enum xpm_keyword_index
3115 XPM_TYPE,
3116 XPM_FILE,
3117 XPM_DATA,
3118 XPM_ASCENT,
3119 XPM_MARGIN,
3120 XPM_RELIEF,
3121 XPM_ALGORITHM,
3122 XPM_HEURISTIC_MASK,
3123 XPM_MASK,
3124 XPM_COLOR_SYMBOLS,
3125 XPM_BACKGROUND,
3126 XPM_LAST
3129 /* Vector of image_keyword structures describing the format
3130 of valid XPM image specifications. */
3132 static const struct image_keyword xpm_format[XPM_LAST] =
3134 {":type", IMAGE_SYMBOL_VALUE, 1},
3135 {":file", IMAGE_STRING_VALUE, 0},
3136 {":data", IMAGE_STRING_VALUE, 0},
3137 {":ascent", IMAGE_ASCENT_VALUE, 0},
3138 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
3139 {":relief", IMAGE_INTEGER_VALUE, 0},
3140 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3141 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3142 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3143 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3144 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
3147 #if defined HAVE_NTGUI && defined WINDOWSNT
3148 static bool init_xpm_functions (void);
3149 #else
3150 #define init_xpm_functions NULL
3151 #endif
3153 /* Structure describing the image type XPM. */
3155 static struct image_type xpm_type =
3157 &Qxpm,
3158 xpm_image_p,
3159 xpm_load,
3160 x_clear_image,
3161 init_xpm_functions,
3162 NULL
3165 #ifdef HAVE_X_WINDOWS
3167 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
3168 functions for allocating image colors. Our own functions handle
3169 color allocation failures more gracefully than the ones on the XPM
3170 lib. */
3172 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
3173 #define ALLOC_XPM_COLORS
3174 #endif
3175 #endif /* HAVE_X_WINDOWS */
3177 #ifdef ALLOC_XPM_COLORS
3179 static struct xpm_cached_color *xpm_cache_color (struct frame *, char *,
3180 XColor *, int);
3182 /* An entry in a hash table used to cache color definitions of named
3183 colors. This cache is necessary to speed up XPM image loading in
3184 case we do color allocations ourselves. Without it, we would need
3185 a call to XParseColor per pixel in the image. */
3187 struct xpm_cached_color
3189 /* Next in collision chain. */
3190 struct xpm_cached_color *next;
3192 /* Color definition (RGB and pixel color). */
3193 XColor color;
3195 /* Color name. */
3196 char name[FLEXIBLE_ARRAY_MEMBER];
3199 /* The hash table used for the color cache, and its bucket vector
3200 size. */
3202 #define XPM_COLOR_CACHE_BUCKETS 1001
3203 static struct xpm_cached_color **xpm_color_cache;
3205 /* Initialize the color cache. */
3207 static void
3208 xpm_init_color_cache (struct frame *f, XpmAttributes *attrs)
3210 size_t nbytes = XPM_COLOR_CACHE_BUCKETS * sizeof *xpm_color_cache;
3211 xpm_color_cache = xzalloc (nbytes);
3212 init_color_table ();
3214 if (attrs->valuemask & XpmColorSymbols)
3216 int i;
3217 XColor color;
3219 for (i = 0; i < attrs->numsymbols; ++i)
3220 if (XParseColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
3221 attrs->colorsymbols[i].value, &color))
3223 color.pixel = lookup_rgb_color (f, color.red, color.green,
3224 color.blue);
3225 xpm_cache_color (f, attrs->colorsymbols[i].name, &color, -1);
3230 /* Free the color cache. */
3232 static void
3233 xpm_free_color_cache (void)
3235 struct xpm_cached_color *p, *next;
3236 int i;
3238 for (i = 0; i < XPM_COLOR_CACHE_BUCKETS; ++i)
3239 for (p = xpm_color_cache[i]; p; p = next)
3241 next = p->next;
3242 xfree (p);
3245 xfree (xpm_color_cache);
3246 xpm_color_cache = NULL;
3247 free_color_table ();
3250 /* Return the bucket index for color named COLOR_NAME in the color
3251 cache. */
3253 static int
3254 xpm_color_bucket (char *color_name)
3256 EMACS_UINT hash = hash_string (color_name, strlen (color_name));
3257 return hash % XPM_COLOR_CACHE_BUCKETS;
3261 /* On frame F, cache values COLOR for color with name COLOR_NAME.
3262 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
3263 entry added. */
3265 static struct xpm_cached_color *
3266 xpm_cache_color (struct frame *f, char *color_name, XColor *color, int bucket)
3268 size_t nbytes;
3269 struct xpm_cached_color *p;
3271 if (bucket < 0)
3272 bucket = xpm_color_bucket (color_name);
3274 nbytes = offsetof (struct xpm_cached_color, name) + strlen (color_name) + 1;
3275 p = xmalloc (nbytes);
3276 strcpy (p->name, color_name);
3277 p->color = *color;
3278 p->next = xpm_color_cache[bucket];
3279 xpm_color_cache[bucket] = p;
3280 return p;
3283 /* Look up color COLOR_NAME for frame F in the color cache. If found,
3284 return the cached definition in *COLOR. Otherwise, make a new
3285 entry in the cache and allocate the color. Value is false if color
3286 allocation failed. */
3288 static bool
3289 xpm_lookup_color (struct frame *f, char *color_name, XColor *color)
3291 struct xpm_cached_color *p;
3292 int h = xpm_color_bucket (color_name);
3294 for (p = xpm_color_cache[h]; p; p = p->next)
3295 if (strcmp (p->name, color_name) == 0)
3296 break;
3298 if (p != NULL)
3299 *color = p->color;
3300 else if (XParseColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
3301 color_name, color))
3303 color->pixel = lookup_rgb_color (f, color->red, color->green,
3304 color->blue);
3305 p = xpm_cache_color (f, color_name, color, h);
3307 /* You get `opaque' at least from ImageMagick converting pbm to xpm
3308 with transparency, and it's useful. */
3309 else if (strcmp ("opaque", color_name) == 0)
3311 memset (color, 0, sizeof (XColor)); /* Is this necessary/correct? */
3312 color->pixel = FRAME_FOREGROUND_PIXEL (f);
3313 p = xpm_cache_color (f, color_name, color, h);
3316 return p != NULL;
3320 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
3321 CLOSURE is a pointer to the frame on which we allocate the
3322 color. Return in *COLOR the allocated color. Value is non-zero
3323 if successful. */
3325 static int
3326 xpm_alloc_color (Display *dpy, Colormap cmap, char *color_name, XColor *color,
3327 void *closure)
3329 return xpm_lookup_color (closure, color_name, color);
3333 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
3334 is a pointer to the frame on which we allocate the color. Value is
3335 non-zero if successful. */
3337 static int
3338 xpm_free_colors (Display *dpy, Colormap cmap, Pixel *pixels, int npixels, void *closure)
3340 return 1;
3343 #endif /* ALLOC_XPM_COLORS */
3346 #ifdef WINDOWSNT
3348 /* XPM library details. */
3350 DEF_IMGLIB_FN (void, XpmFreeAttributes, (XpmAttributes *));
3351 DEF_IMGLIB_FN (int, XpmCreateImageFromBuffer, (Display *, char *, xpm_XImage **,
3352 xpm_XImage **, XpmAttributes *));
3353 DEF_IMGLIB_FN (int, XpmReadFileToImage, (Display *, char *, xpm_XImage **,
3354 xpm_XImage **, XpmAttributes *));
3355 DEF_IMGLIB_FN (void, XImageFree, (xpm_XImage *));
3357 static bool
3358 init_xpm_functions (void)
3360 HMODULE library;
3362 if (!(library = w32_delayed_load (Qxpm)))
3363 return 0;
3365 LOAD_IMGLIB_FN (library, XpmFreeAttributes);
3366 LOAD_IMGLIB_FN (library, XpmCreateImageFromBuffer);
3367 LOAD_IMGLIB_FN (library, XpmReadFileToImage);
3368 LOAD_IMGLIB_FN (library, XImageFree);
3369 return 1;
3372 #endif /* WINDOWSNT */
3374 #if defined HAVE_NTGUI && !defined WINDOWSNT
3375 /* Glue for code below */
3376 #define fn_XpmReadFileToImage XpmReadFileToImage
3377 #define fn_XpmCreateImageFromBuffer XpmCreateImageFromBuffer
3378 #define fn_XImageFree XImageFree
3379 #define fn_XpmFreeAttributes XpmFreeAttributes
3380 #endif /* HAVE_NTGUI && !WINDOWSNT */
3382 /* Value is true if COLOR_SYMBOLS is a valid color symbols list
3383 for XPM images. Such a list must consist of conses whose car and
3384 cdr are strings. */
3386 static bool
3387 xpm_valid_color_symbols_p (Lisp_Object color_symbols)
3389 while (CONSP (color_symbols))
3391 Lisp_Object sym = XCAR (color_symbols);
3392 if (!CONSP (sym)
3393 || !STRINGP (XCAR (sym))
3394 || !STRINGP (XCDR (sym)))
3395 break;
3396 color_symbols = XCDR (color_symbols);
3399 return NILP (color_symbols);
3403 /* Value is true if OBJECT is a valid XPM image specification. */
3405 static bool
3406 xpm_image_p (Lisp_Object object)
3408 struct image_keyword fmt[XPM_LAST];
3409 memcpy (fmt, xpm_format, sizeof fmt);
3410 return (parse_image_spec (object, fmt, XPM_LAST, Qxpm)
3411 /* Either `:file' or `:data' must be present. */
3412 && fmt[XPM_FILE].count + fmt[XPM_DATA].count == 1
3413 /* Either no `:color-symbols' or it's a list of conses
3414 whose car and cdr are strings. */
3415 && (fmt[XPM_COLOR_SYMBOLS].count == 0
3416 || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
3419 #endif /* HAVE_XPM || HAVE_NS */
3421 #if defined HAVE_XPM && defined HAVE_X_WINDOWS && !defined USE_GTK
3422 ptrdiff_t
3423 x_create_bitmap_from_xpm_data (struct frame *f, const char **bits)
3425 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
3426 ptrdiff_t id;
3427 int rc;
3428 XpmAttributes attrs;
3429 Pixmap bitmap, mask;
3431 memset (&attrs, 0, sizeof attrs);
3433 attrs.visual = FRAME_X_VISUAL (f);
3434 attrs.colormap = FRAME_X_COLORMAP (f);
3435 attrs.valuemask |= XpmVisual;
3436 attrs.valuemask |= XpmColormap;
3438 rc = XpmCreatePixmapFromData (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3439 (char **) bits, &bitmap, &mask, &attrs);
3440 if (rc != XpmSuccess)
3442 XpmFreeAttributes (&attrs);
3443 return -1;
3446 id = x_allocate_bitmap_record (f);
3447 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
3448 dpyinfo->bitmaps[id - 1].have_mask = 1;
3449 dpyinfo->bitmaps[id - 1].mask = mask;
3450 dpyinfo->bitmaps[id - 1].file = NULL;
3451 dpyinfo->bitmaps[id - 1].height = attrs.height;
3452 dpyinfo->bitmaps[id - 1].width = attrs.width;
3453 dpyinfo->bitmaps[id - 1].depth = attrs.depth;
3454 dpyinfo->bitmaps[id - 1].refcount = 1;
3456 XpmFreeAttributes (&attrs);
3457 return id;
3459 #endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */
3461 /* Load image IMG which will be displayed on frame F. Value is
3462 true if successful. */
3464 #ifdef HAVE_XPM
3466 static bool
3467 xpm_load (struct frame *f, struct image *img)
3469 int rc;
3470 XpmAttributes attrs;
3471 Lisp_Object specified_file, color_symbols;
3472 #ifdef HAVE_NTGUI
3473 HDC hdc;
3474 xpm_XImage * xpm_image = NULL, * xpm_mask = NULL;
3475 #endif /* HAVE_NTGUI */
3477 /* Configure the XPM lib. Use the visual of frame F. Allocate
3478 close colors. Return colors allocated. */
3479 memset (&attrs, 0, sizeof attrs);
3481 #ifndef HAVE_NTGUI
3482 attrs.visual = FRAME_X_VISUAL (f);
3483 attrs.colormap = FRAME_X_COLORMAP (f);
3484 attrs.valuemask |= XpmVisual;
3485 attrs.valuemask |= XpmColormap;
3486 #endif /* HAVE_NTGUI */
3488 #ifdef ALLOC_XPM_COLORS
3489 /* Allocate colors with our own functions which handle
3490 failing color allocation more gracefully. */
3491 attrs.color_closure = f;
3492 attrs.alloc_color = xpm_alloc_color;
3493 attrs.free_colors = xpm_free_colors;
3494 attrs.valuemask |= XpmAllocColor | XpmFreeColors | XpmColorClosure;
3495 #else /* not ALLOC_XPM_COLORS */
3496 /* Let the XPM lib allocate colors. */
3497 attrs.valuemask |= XpmReturnAllocPixels;
3498 #ifdef XpmAllocCloseColors
3499 attrs.alloc_close_colors = 1;
3500 attrs.valuemask |= XpmAllocCloseColors;
3501 #else /* not XpmAllocCloseColors */
3502 attrs.closeness = 600;
3503 attrs.valuemask |= XpmCloseness;
3504 #endif /* not XpmAllocCloseColors */
3505 #endif /* ALLOC_XPM_COLORS */
3507 /* If image specification contains symbolic color definitions, add
3508 these to `attrs'. */
3509 color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL);
3510 if (CONSP (color_symbols))
3512 Lisp_Object tail;
3513 XpmColorSymbol *xpm_syms;
3514 int i, size;
3516 attrs.valuemask |= XpmColorSymbols;
3518 /* Count number of symbols. */
3519 attrs.numsymbols = 0;
3520 for (tail = color_symbols; CONSP (tail); tail = XCDR (tail))
3521 ++attrs.numsymbols;
3523 /* Allocate an XpmColorSymbol array. */
3524 size = attrs.numsymbols * sizeof *xpm_syms;
3525 xpm_syms = alloca (size);
3526 memset (xpm_syms, 0, size);
3527 attrs.colorsymbols = xpm_syms;
3529 /* Fill the color symbol array. */
3530 for (tail = color_symbols, i = 0;
3531 CONSP (tail);
3532 ++i, tail = XCDR (tail))
3534 Lisp_Object name;
3535 Lisp_Object color;
3536 char *empty_string = (char *) "";
3538 if (!CONSP (XCAR (tail)))
3540 xpm_syms[i].name = empty_string;
3541 xpm_syms[i].value = empty_string;
3542 continue;
3544 name = XCAR (XCAR (tail));
3545 color = XCDR (XCAR (tail));
3546 if (STRINGP (name))
3548 xpm_syms[i].name = alloca (SCHARS (name) + 1);
3549 strcpy (xpm_syms[i].name, SSDATA (name));
3551 else
3552 xpm_syms[i].name = empty_string;
3553 if (STRINGP (color))
3555 xpm_syms[i].value = alloca (SCHARS (color) + 1);
3556 strcpy (xpm_syms[i].value, SSDATA (color));
3558 else
3559 xpm_syms[i].value = empty_string;
3563 /* Create a pixmap for the image, either from a file, or from a
3564 string buffer containing data in the same format as an XPM file. */
3565 #ifdef ALLOC_XPM_COLORS
3566 xpm_init_color_cache (f, &attrs);
3567 #endif
3569 specified_file = image_spec_value (img->spec, QCfile, NULL);
3571 #ifdef HAVE_NTGUI
3573 HDC frame_dc = get_frame_dc (f);
3574 hdc = CreateCompatibleDC (frame_dc);
3575 release_frame_dc (f, frame_dc);
3577 #endif /* HAVE_NTGUI */
3579 if (STRINGP (specified_file))
3581 Lisp_Object file = x_find_image_file (specified_file);
3582 if (!STRINGP (file))
3584 image_error ("Cannot find image file `%s'", specified_file, Qnil);
3585 #ifdef ALLOC_XPM_COLORS
3586 xpm_free_color_cache ();
3587 #endif
3588 return 0;
3591 #ifdef HAVE_NTGUI
3592 /* XpmReadFileToPixmap is not available in the Windows port of
3593 libxpm. But XpmReadFileToImage almost does what we want. */
3594 rc = fn_XpmReadFileToImage (&hdc, SDATA (file),
3595 &xpm_image, &xpm_mask,
3596 &attrs);
3597 #else
3598 rc = XpmReadFileToImage (FRAME_X_DISPLAY (f), SSDATA (file),
3599 &img->ximg, &img->mask_img,
3600 &attrs);
3601 #endif /* HAVE_NTGUI */
3603 else
3605 Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);
3606 if (!STRINGP (buffer))
3608 image_error ("Invalid image data `%s'", buffer, Qnil);
3609 #ifdef ALLOC_XPM_COLORS
3610 xpm_free_color_cache ();
3611 #endif
3612 return 0;
3614 #ifdef HAVE_NTGUI
3615 /* XpmCreatePixmapFromBuffer is not available in the Windows port
3616 of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
3617 rc = fn_XpmCreateImageFromBuffer (&hdc, SDATA (buffer),
3618 &xpm_image, &xpm_mask,
3619 &attrs);
3620 #else
3621 rc = XpmCreateImageFromBuffer (FRAME_X_DISPLAY (f), SSDATA (buffer),
3622 &img->ximg, &img->mask_img,
3623 &attrs);
3624 #endif /* HAVE_NTGUI */
3627 #ifdef HAVE_X_WINDOWS
3628 if (rc == XpmSuccess)
3630 img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3631 img->ximg->width, img->ximg->height,
3632 img->ximg->depth);
3633 if (img->pixmap == NO_PIXMAP)
3635 x_clear_image (f, img);
3636 rc = XpmNoMemory;
3638 else if (img->mask_img)
3640 img->mask = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3641 img->mask_img->width,
3642 img->mask_img->height,
3643 img->mask_img->depth);
3644 if (img->mask == NO_PIXMAP)
3646 x_clear_image (f, img);
3647 rc = XpmNoMemory;
3651 #endif
3653 if (rc == XpmSuccess)
3655 #if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS)
3656 img->colors = colors_in_color_table (&img->ncolors);
3657 #else /* not ALLOC_XPM_COLORS */
3658 int i;
3660 #ifdef HAVE_NTGUI
3661 /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
3662 plus some duplicate attributes. */
3663 if (xpm_image && xpm_image->bitmap)
3665 img->pixmap = xpm_image->bitmap;
3666 /* XImageFree in libXpm frees XImage struct without destroying
3667 the bitmap, which is what we want. */
3668 fn_XImageFree (xpm_image);
3670 if (xpm_mask && xpm_mask->bitmap)
3672 /* The mask appears to be inverted compared with what we expect.
3673 TODO: invert our expectations. See other places where we
3674 have to invert bits because our idea of masks is backwards. */
3675 HGDIOBJ old_obj;
3676 old_obj = SelectObject (hdc, xpm_mask->bitmap);
3678 PatBlt (hdc, 0, 0, xpm_mask->width, xpm_mask->height, DSTINVERT);
3679 SelectObject (hdc, old_obj);
3681 img->mask = xpm_mask->bitmap;
3682 fn_XImageFree (xpm_mask);
3683 DeleteDC (hdc);
3686 DeleteDC (hdc);
3687 #endif /* HAVE_NTGUI */
3689 /* Remember allocated colors. */
3690 img->colors = xnmalloc (attrs.nalloc_pixels, sizeof *img->colors);
3691 img->ncolors = attrs.nalloc_pixels;
3692 for (i = 0; i < attrs.nalloc_pixels; ++i)
3694 img->colors[i] = attrs.alloc_pixels[i];
3695 #ifdef DEBUG_X_COLORS
3696 register_color (img->colors[i]);
3697 #endif
3699 #endif /* not ALLOC_XPM_COLORS */
3701 img->width = attrs.width;
3702 img->height = attrs.height;
3703 eassert (img->width > 0 && img->height > 0);
3705 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
3706 #ifdef HAVE_NTGUI
3707 fn_XpmFreeAttributes (&attrs);
3708 #else
3709 XpmFreeAttributes (&attrs);
3710 #endif /* HAVE_NTGUI */
3712 #ifdef HAVE_X_WINDOWS
3713 /* Maybe fill in the background field while we have ximg handy. */
3714 IMAGE_BACKGROUND (img, f, img->ximg);
3715 if (img->mask_img)
3716 /* Fill in the background_transparent field while we have the
3717 mask handy. */
3718 image_background_transparent (img, f, img->mask_img);
3719 #endif
3721 else
3723 #ifdef HAVE_NTGUI
3724 DeleteDC (hdc);
3725 #endif /* HAVE_NTGUI */
3727 switch (rc)
3729 case XpmOpenFailed:
3730 image_error ("Error opening XPM file (%s)", img->spec, Qnil);
3731 break;
3733 case XpmFileInvalid:
3734 image_error ("Invalid XPM file (%s)", img->spec, Qnil);
3735 break;
3737 case XpmNoMemory:
3738 image_error ("Out of memory (%s)", img->spec, Qnil);
3739 break;
3741 case XpmColorFailed:
3742 image_error ("Color allocation error (%s)", img->spec, Qnil);
3743 break;
3745 default:
3746 image_error ("Unknown error (%s)", img->spec, Qnil);
3747 break;
3751 #ifdef ALLOC_XPM_COLORS
3752 xpm_free_color_cache ();
3753 #endif
3754 return rc == XpmSuccess;
3757 #endif /* HAVE_XPM */
3759 #if defined (HAVE_NS) && !defined (HAVE_XPM)
3761 /* XPM support functions for NS where libxpm is not available.
3762 Only XPM version 3 (without any extensions) is supported. */
3764 static void xpm_put_color_table_v (Lisp_Object, const unsigned char *,
3765 int, Lisp_Object);
3766 static Lisp_Object xpm_get_color_table_v (Lisp_Object,
3767 const unsigned char *, int);
3768 static void xpm_put_color_table_h (Lisp_Object, const unsigned char *,
3769 int, Lisp_Object);
3770 static Lisp_Object xpm_get_color_table_h (Lisp_Object,
3771 const unsigned char *, int);
3773 /* Tokens returned from xpm_scan. */
3775 enum xpm_token
3777 XPM_TK_IDENT = 256,
3778 XPM_TK_STRING,
3779 XPM_TK_EOF
3782 /* Scan an XPM data and return a character (< 256) or a token defined
3783 by enum xpm_token above. *S and END are the start (inclusive) and
3784 the end (exclusive) addresses of the data, respectively. Advance
3785 *S while scanning. If token is either XPM_TK_IDENT or
3786 XPM_TK_STRING, *BEG and *LEN are set to the start address and the
3787 length of the corresponding token, respectively. */
3789 static int
3790 xpm_scan (const unsigned char **s,
3791 const unsigned char *end,
3792 const unsigned char **beg,
3793 ptrdiff_t *len)
3795 int c;
3797 while (*s < end)
3799 /* Skip white-space. */
3800 while (*s < end && (c = *(*s)++, c_isspace (c)))
3803 /* gnus-pointer.xpm uses '-' in its identifier.
3804 sb-dir-plus.xpm uses '+' in its identifier. */
3805 if (c_isalpha (c) || c == '_' || c == '-' || c == '+')
3807 *beg = *s - 1;
3808 while (*s < end
3809 && (c = **s, c_isalnum (c)
3810 || c == '_' || c == '-' || c == '+'))
3811 ++*s;
3812 *len = *s - *beg;
3813 return XPM_TK_IDENT;
3815 else if (c == '"')
3817 *beg = *s;
3818 while (*s < end && **s != '"')
3819 ++*s;
3820 *len = *s - *beg;
3821 if (*s < end)
3822 ++*s;
3823 return XPM_TK_STRING;
3825 else if (c == '/')
3827 if (*s < end && **s == '*')
3829 /* C-style comment. */
3830 ++*s;
3833 while (*s < end && *(*s)++ != '*')
3836 while (*s < end && **s != '/');
3837 if (*s < end)
3838 ++*s;
3840 else
3841 return c;
3843 else
3844 return c;
3847 return XPM_TK_EOF;
3850 /* Functions for color table lookup in XPM data. A key is a string
3851 specifying the color of each pixel in XPM data. A value is either
3852 an integer that specifies a pixel color, Qt that specifies
3853 transparency, or Qnil for the unspecified color. If the length of
3854 the key string is one, a vector is used as a table. Otherwise, a
3855 hash table is used. */
3857 static Lisp_Object
3858 xpm_make_color_table_v (void (**put_func) (Lisp_Object,
3859 const unsigned char *,
3860 int,
3861 Lisp_Object),
3862 Lisp_Object (**get_func) (Lisp_Object,
3863 const unsigned char *,
3864 int))
3866 *put_func = xpm_put_color_table_v;
3867 *get_func = xpm_get_color_table_v;
3868 return Fmake_vector (make_number (256), Qnil);
3871 static void
3872 xpm_put_color_table_v (Lisp_Object color_table,
3873 const unsigned char *chars_start,
3874 int chars_len,
3875 Lisp_Object color)
3877 ASET (color_table, *chars_start, color);
3880 static Lisp_Object
3881 xpm_get_color_table_v (Lisp_Object color_table,
3882 const unsigned char *chars_start,
3883 int chars_len)
3885 return AREF (color_table, *chars_start);
3888 static Lisp_Object
3889 xpm_make_color_table_h (void (**put_func) (Lisp_Object,
3890 const unsigned char *,
3891 int,
3892 Lisp_Object),
3893 Lisp_Object (**get_func) (Lisp_Object,
3894 const unsigned char *,
3895 int))
3897 *put_func = xpm_put_color_table_h;
3898 *get_func = xpm_get_color_table_h;
3899 return make_hash_table (hashtest_equal, make_number (DEFAULT_HASH_SIZE),
3900 make_float (DEFAULT_REHASH_SIZE),
3901 make_float (DEFAULT_REHASH_THRESHOLD),
3902 Qnil);
3905 static void
3906 xpm_put_color_table_h (Lisp_Object color_table,
3907 const unsigned char *chars_start,
3908 int chars_len,
3909 Lisp_Object color)
3911 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
3912 EMACS_UINT hash_code;
3913 Lisp_Object chars = make_unibyte_string (chars_start, chars_len);
3915 hash_lookup (table, chars, &hash_code);
3916 hash_put (table, chars, color, hash_code);
3919 static Lisp_Object
3920 xpm_get_color_table_h (Lisp_Object color_table,
3921 const unsigned char *chars_start,
3922 int chars_len)
3924 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
3925 ptrdiff_t i =
3926 hash_lookup (table, make_unibyte_string (chars_start, chars_len), NULL);
3928 return i >= 0 ? HASH_VALUE (table, i) : Qnil;
3931 enum xpm_color_key {
3932 XPM_COLOR_KEY_S,
3933 XPM_COLOR_KEY_M,
3934 XPM_COLOR_KEY_G4,
3935 XPM_COLOR_KEY_G,
3936 XPM_COLOR_KEY_C
3939 static const char xpm_color_key_strings[][4] = {"s", "m", "g4", "g", "c"};
3941 static int
3942 xpm_str_to_color_key (const char *s)
3944 int i;
3946 for (i = 0;
3947 i < sizeof xpm_color_key_strings / sizeof xpm_color_key_strings[0];
3948 i++)
3949 if (strcmp (xpm_color_key_strings[i], s) == 0)
3950 return i;
3951 return -1;
3954 static bool
3955 xpm_load_image (struct frame *f,
3956 struct image *img,
3957 const unsigned char *contents,
3958 const unsigned char *end)
3960 const unsigned char *s = contents, *beg, *str;
3961 unsigned char buffer[BUFSIZ];
3962 int width, height, x, y;
3963 int num_colors, chars_per_pixel;
3964 ptrdiff_t len;
3965 int LA1;
3966 void (*put_color_table) (Lisp_Object, const unsigned char *, int, Lisp_Object);
3967 Lisp_Object (*get_color_table) (Lisp_Object, const unsigned char *, int);
3968 Lisp_Object frame, color_symbols, color_table;
3969 int best_key;
3970 bool have_mask = 0;
3971 XImagePtr ximg = NULL, mask_img = NULL;
3973 #define match() \
3974 LA1 = xpm_scan (&s, end, &beg, &len)
3976 #define expect(TOKEN) \
3977 do \
3979 if (LA1 != (TOKEN)) \
3980 goto failure; \
3981 match (); \
3983 while (0)
3985 #define expect_ident(IDENT) \
3986 if (LA1 == XPM_TK_IDENT \
3987 && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
3988 match (); \
3989 else \
3990 goto failure
3992 if (!(end - s >= 9 && memcmp (s, "/* XPM */", 9) == 0))
3993 goto failure;
3994 s += 9;
3995 match ();
3996 expect_ident ("static");
3997 expect_ident ("char");
3998 expect ('*');
3999 expect (XPM_TK_IDENT);
4000 expect ('[');
4001 expect (']');
4002 expect ('=');
4003 expect ('{');
4004 expect (XPM_TK_STRING);
4005 if (len >= BUFSIZ)
4006 goto failure;
4007 memcpy (buffer, beg, len);
4008 buffer[len] = '\0';
4009 if (sscanf (buffer, "%d %d %d %d", &width, &height,
4010 &num_colors, &chars_per_pixel) != 4
4011 || width <= 0 || height <= 0
4012 || num_colors <= 0 || chars_per_pixel <= 0)
4013 goto failure;
4015 if (!check_image_size (f, width, height))
4017 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
4018 goto failure;
4021 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)
4022 #ifndef HAVE_NS
4023 || !image_create_x_image_and_pixmap (f, img, width, height, 1,
4024 &mask_img, 1)
4025 #endif
4028 image_error ("Image too large", Qnil, Qnil);
4029 goto failure;
4032 expect (',');
4034 XSETFRAME (frame, f);
4035 if (!NILP (Fxw_display_color_p (frame)))
4036 best_key = XPM_COLOR_KEY_C;
4037 else if (!NILP (Fx_display_grayscale_p (frame)))
4038 best_key = (XFASTINT (Fx_display_planes (frame)) > 2
4039 ? XPM_COLOR_KEY_G : XPM_COLOR_KEY_G4);
4040 else
4041 best_key = XPM_COLOR_KEY_M;
4043 color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL);
4044 if (chars_per_pixel == 1)
4045 color_table = xpm_make_color_table_v (&put_color_table,
4046 &get_color_table);
4047 else
4048 color_table = xpm_make_color_table_h (&put_color_table,
4049 &get_color_table);
4051 while (num_colors-- > 0)
4053 char *color, *max_color;
4054 int key, next_key, max_key = 0;
4055 Lisp_Object symbol_color = Qnil, color_val;
4056 XColor cdef;
4058 expect (XPM_TK_STRING);
4059 if (len <= chars_per_pixel || len >= BUFSIZ + chars_per_pixel)
4060 goto failure;
4061 memcpy (buffer, beg + chars_per_pixel, len - chars_per_pixel);
4062 buffer[len - chars_per_pixel] = '\0';
4064 str = strtok (buffer, " \t");
4065 if (str == NULL)
4066 goto failure;
4067 key = xpm_str_to_color_key (str);
4068 if (key < 0)
4069 goto failure;
4072 color = strtok (NULL, " \t");
4073 if (color == NULL)
4074 goto failure;
4076 while ((str = strtok (NULL, " \t")) != NULL)
4078 next_key = xpm_str_to_color_key (str);
4079 if (next_key >= 0)
4080 break;
4081 color[strlen (color)] = ' ';
4084 if (key == XPM_COLOR_KEY_S)
4086 if (NILP (symbol_color))
4087 symbol_color = build_string (color);
4089 else if (max_key < key && key <= best_key)
4091 max_key = key;
4092 max_color = color;
4094 key = next_key;
4096 while (str);
4098 color_val = Qnil;
4099 if (!NILP (color_symbols) && !NILP (symbol_color))
4101 Lisp_Object specified_color = Fassoc (symbol_color, color_symbols);
4103 if (CONSP (specified_color) && STRINGP (XCDR (specified_color)))
4105 if (xstrcasecmp (SSDATA (XCDR (specified_color)), "None") == 0)
4106 color_val = Qt;
4107 else if (x_defined_color (f, SSDATA (XCDR (specified_color)),
4108 &cdef, 0))
4109 color_val = make_number (cdef.pixel);
4112 if (NILP (color_val) && max_key > 0)
4114 if (xstrcasecmp (max_color, "None") == 0)
4115 color_val = Qt;
4116 else if (x_defined_color (f, max_color, &cdef, 0))
4117 color_val = make_number (cdef.pixel);
4119 if (!NILP (color_val))
4120 (*put_color_table) (color_table, beg, chars_per_pixel, color_val);
4122 expect (',');
4125 for (y = 0; y < height; y++)
4127 expect (XPM_TK_STRING);
4128 str = beg;
4129 if (len < width * chars_per_pixel)
4130 goto failure;
4131 for (x = 0; x < width; x++, str += chars_per_pixel)
4133 Lisp_Object color_val =
4134 (*get_color_table) (color_table, str, chars_per_pixel);
4136 XPutPixel (ximg, x, y,
4137 (INTEGERP (color_val) ? XINT (color_val)
4138 : FRAME_FOREGROUND_PIXEL (f)));
4139 #ifndef HAVE_NS
4140 XPutPixel (mask_img, x, y,
4141 (!EQ (color_val, Qt) ? PIX_MASK_DRAW
4142 : (have_mask = 1, PIX_MASK_RETAIN)));
4143 #else
4144 if (EQ (color_val, Qt))
4145 ns_set_alpha (ximg, x, y, 0);
4146 #endif
4148 if (y + 1 < height)
4149 expect (',');
4152 img->width = width;
4153 img->height = height;
4155 /* Maybe fill in the background field while we have ximg handy. */
4156 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
4157 IMAGE_BACKGROUND (img, f, ximg);
4159 image_put_x_image (f, img, ximg, 0);
4160 #ifndef HAVE_NS
4161 if (have_mask)
4163 /* Fill in the background_transparent field while we have the
4164 mask handy. */
4165 image_background_transparent (img, f, mask_img);
4167 image_put_x_image (f, img, mask_img, 1);
4169 else
4171 x_destroy_x_image (mask_img);
4172 x_clear_image_1 (f, img, CLEAR_IMAGE_MASK);
4174 #endif
4175 return 1;
4177 failure:
4178 image_error ("Invalid XPM file (%s)", img->spec, Qnil);
4179 x_destroy_x_image (ximg);
4180 x_destroy_x_image (mask_img);
4181 x_clear_image (f, img);
4182 return 0;
4184 #undef match
4185 #undef expect
4186 #undef expect_ident
4189 static bool
4190 xpm_load (struct frame *f,
4191 struct image *img)
4193 bool success_p = 0;
4194 Lisp_Object file_name;
4196 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4197 file_name = image_spec_value (img->spec, QCfile, NULL);
4198 if (STRINGP (file_name))
4200 Lisp_Object file;
4201 unsigned char *contents;
4202 ptrdiff_t size;
4204 file = x_find_image_file (file_name);
4205 if (!STRINGP (file))
4207 image_error ("Cannot find image file `%s'", file_name, Qnil);
4208 return 0;
4211 contents = slurp_file (SSDATA (file), &size);
4212 if (contents == NULL)
4214 image_error ("Error loading XPM image `%s'", img->spec, Qnil);
4215 return 0;
4218 success_p = xpm_load_image (f, img, contents, contents + size);
4219 xfree (contents);
4221 else
4223 Lisp_Object data;
4225 data = image_spec_value (img->spec, QCdata, NULL);
4226 if (!STRINGP (data))
4228 image_error ("Invalid image data `%s'", data, Qnil);
4229 return 0;
4231 success_p = xpm_load_image (f, img, SDATA (data),
4232 SDATA (data) + SBYTES (data));
4235 return success_p;
4238 #endif /* HAVE_NS && !HAVE_XPM */
4242 /***********************************************************************
4243 Color table
4244 ***********************************************************************/
4246 #ifdef COLOR_TABLE_SUPPORT
4248 /* An entry in the color table mapping an RGB color to a pixel color. */
4250 struct ct_color
4252 int r, g, b;
4253 unsigned long pixel;
4255 /* Next in color table collision list. */
4256 struct ct_color *next;
4259 /* The bucket vector size to use. Must be prime. */
4261 #define CT_SIZE 101
4263 /* Value is a hash of the RGB color given by R, G, and B. */
4265 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
4267 /* The color hash table. */
4269 static struct ct_color **ct_table;
4271 /* Number of entries in the color table. */
4273 static int ct_colors_allocated;
4274 enum
4276 ct_colors_allocated_max =
4277 min (INT_MAX,
4278 min (PTRDIFF_MAX, SIZE_MAX) / sizeof (unsigned long))
4281 /* Initialize the color table. */
4283 static void
4284 init_color_table (void)
4286 int size = CT_SIZE * sizeof (*ct_table);
4287 ct_table = xzalloc (size);
4288 ct_colors_allocated = 0;
4292 /* Free memory associated with the color table. */
4294 static void
4295 free_color_table (void)
4297 int i;
4298 struct ct_color *p, *next;
4300 for (i = 0; i < CT_SIZE; ++i)
4301 for (p = ct_table[i]; p; p = next)
4303 next = p->next;
4304 xfree (p);
4307 xfree (ct_table);
4308 ct_table = NULL;
4312 /* Value is a pixel color for RGB color R, G, B on frame F. If an
4313 entry for that color already is in the color table, return the
4314 pixel color of that entry. Otherwise, allocate a new color for R,
4315 G, B, and make an entry in the color table. */
4317 static unsigned long
4318 lookup_rgb_color (struct frame *f, int r, int g, int b)
4320 unsigned hash = CT_HASH_RGB (r, g, b);
4321 int i = hash % CT_SIZE;
4322 struct ct_color *p;
4323 Display_Info *dpyinfo;
4325 /* Handle TrueColor visuals specially, which improves performance by
4326 two orders of magnitude. Freeing colors on TrueColor visuals is
4327 a nop, and pixel colors specify RGB values directly. See also
4328 the Xlib spec, chapter 3.1. */
4329 dpyinfo = FRAME_DISPLAY_INFO (f);
4330 if (dpyinfo->red_bits > 0)
4332 unsigned long pr, pg, pb;
4334 /* Apply gamma-correction like normal color allocation does. */
4335 if (f->gamma)
4337 XColor color;
4338 color.red = r, color.green = g, color.blue = b;
4339 gamma_correct (f, &color);
4340 r = color.red, g = color.green, b = color.blue;
4343 /* Scale down RGB values to the visual's bits per RGB, and shift
4344 them to the right position in the pixel color. Note that the
4345 original RGB values are 16-bit values, as usual in X. */
4346 pr = (r >> (16 - dpyinfo->red_bits)) << dpyinfo->red_offset;
4347 pg = (g >> (16 - dpyinfo->green_bits)) << dpyinfo->green_offset;
4348 pb = (b >> (16 - dpyinfo->blue_bits)) << dpyinfo->blue_offset;
4350 /* Assemble the pixel color. */
4351 return pr | pg | pb;
4354 for (p = ct_table[i]; p; p = p->next)
4355 if (p->r == r && p->g == g && p->b == b)
4356 break;
4358 if (p == NULL)
4361 #ifdef HAVE_X_WINDOWS
4362 XColor color;
4363 Colormap cmap;
4364 bool rc;
4365 #else
4366 COLORREF color;
4367 #endif
4369 if (ct_colors_allocated_max <= ct_colors_allocated)
4370 return FRAME_FOREGROUND_PIXEL (f);
4372 #ifdef HAVE_X_WINDOWS
4373 color.red = r;
4374 color.green = g;
4375 color.blue = b;
4377 cmap = FRAME_X_COLORMAP (f);
4378 rc = x_alloc_nearest_color (f, cmap, &color);
4379 if (rc)
4381 ++ct_colors_allocated;
4382 p = xmalloc (sizeof *p);
4383 p->r = r;
4384 p->g = g;
4385 p->b = b;
4386 p->pixel = color.pixel;
4387 p->next = ct_table[i];
4388 ct_table[i] = p;
4390 else
4391 return FRAME_FOREGROUND_PIXEL (f);
4393 #else
4394 #ifdef HAVE_NTGUI
4395 color = PALETTERGB (r, g, b);
4396 #else
4397 color = RGB_TO_ULONG (r, g, b);
4398 #endif /* HAVE_NTGUI */
4399 ++ct_colors_allocated;
4400 p = xmalloc (sizeof *p);
4401 p->r = r;
4402 p->g = g;
4403 p->b = b;
4404 p->pixel = color;
4405 p->next = ct_table[i];
4406 ct_table[i] = p;
4407 #endif /* HAVE_X_WINDOWS */
4411 return p->pixel;
4415 /* Look up pixel color PIXEL which is used on frame F in the color
4416 table. If not already present, allocate it. Value is PIXEL. */
4418 static unsigned long
4419 lookup_pixel_color (struct frame *f, unsigned long pixel)
4421 int i = pixel % CT_SIZE;
4422 struct ct_color *p;
4424 for (p = ct_table[i]; p; p = p->next)
4425 if (p->pixel == pixel)
4426 break;
4428 if (p == NULL)
4430 XColor color;
4431 Colormap cmap;
4432 bool rc;
4434 if (ct_colors_allocated_max <= ct_colors_allocated)
4435 return FRAME_FOREGROUND_PIXEL (f);
4437 #ifdef HAVE_X_WINDOWS
4438 cmap = FRAME_X_COLORMAP (f);
4439 color.pixel = pixel;
4440 x_query_color (f, &color);
4441 rc = x_alloc_nearest_color (f, cmap, &color);
4442 #else
4443 block_input ();
4444 cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f));
4445 color.pixel = pixel;
4446 XQueryColor (NULL, cmap, &color);
4447 rc = x_alloc_nearest_color (f, cmap, &color);
4448 unblock_input ();
4449 #endif /* HAVE_X_WINDOWS */
4451 if (rc)
4453 ++ct_colors_allocated;
4455 p = xmalloc (sizeof *p);
4456 p->r = color.red;
4457 p->g = color.green;
4458 p->b = color.blue;
4459 p->pixel = pixel;
4460 p->next = ct_table[i];
4461 ct_table[i] = p;
4463 else
4464 return FRAME_FOREGROUND_PIXEL (f);
4466 return p->pixel;
4470 /* Value is a vector of all pixel colors contained in the color table,
4471 allocated via xmalloc. Set *N to the number of colors. */
4473 static unsigned long *
4474 colors_in_color_table (int *n)
4476 int i, j;
4477 struct ct_color *p;
4478 unsigned long *colors;
4480 if (ct_colors_allocated == 0)
4482 *n = 0;
4483 colors = NULL;
4485 else
4487 colors = xmalloc (ct_colors_allocated * sizeof *colors);
4488 *n = ct_colors_allocated;
4490 for (i = j = 0; i < CT_SIZE; ++i)
4491 for (p = ct_table[i]; p; p = p->next)
4492 colors[j++] = p->pixel;
4495 return colors;
4498 #else /* COLOR_TABLE_SUPPORT */
4500 static unsigned long
4501 lookup_rgb_color (struct frame *f, int r, int g, int b)
4503 unsigned long pixel;
4505 #ifdef HAVE_NTGUI
4506 pixel = PALETTERGB (r >> 8, g >> 8, b >> 8);
4507 #endif /* HAVE_NTGUI */
4509 #ifdef HAVE_NS
4510 pixel = RGB_TO_ULONG (r >> 8, g >> 8, b >> 8);
4511 #endif /* HAVE_NS */
4512 return pixel;
4515 static void
4516 init_color_table (void)
4519 #endif /* COLOR_TABLE_SUPPORT */
4522 /***********************************************************************
4523 Algorithms
4524 ***********************************************************************/
4526 /* Edge detection matrices for different edge-detection
4527 strategies. */
4529 static int emboss_matrix[9] = {
4530 /* x - 1 x x + 1 */
4531 2, -1, 0, /* y - 1 */
4532 -1, 0, 1, /* y */
4533 0, 1, -2 /* y + 1 */
4536 static int laplace_matrix[9] = {
4537 /* x - 1 x x + 1 */
4538 1, 0, 0, /* y - 1 */
4539 0, 0, 0, /* y */
4540 0, 0, -1 /* y + 1 */
4543 /* Value is the intensity of the color whose red/green/blue values
4544 are R, G, and B. */
4546 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
4549 /* On frame F, return an array of XColor structures describing image
4550 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
4551 means also fill the red/green/blue members of the XColor
4552 structures. Value is a pointer to the array of XColors structures,
4553 allocated with xmalloc; it must be freed by the caller. */
4555 static XColor *
4556 x_to_xcolors (struct frame *f, struct image *img, bool rgb_p)
4558 int x, y;
4559 XColor *colors, *p;
4560 XImagePtr_or_DC ximg;
4561 #ifdef HAVE_NTGUI
4562 HGDIOBJ prev;
4563 #endif /* HAVE_NTGUI */
4565 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *colors / img->width < img->height)
4566 memory_full (SIZE_MAX);
4567 colors = xmalloc (sizeof *colors * img->width * img->height);
4569 /* Get the X image or create a memory device context for IMG. */
4570 ximg = image_get_x_image_or_dc (f, img, 0, &prev);
4572 /* Fill the `pixel' members of the XColor array. I wished there
4573 were an easy and portable way to circumvent XGetPixel. */
4574 p = colors;
4575 for (y = 0; y < img->height; ++y)
4577 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
4578 XColor *row = p;
4579 for (x = 0; x < img->width; ++x, ++p)
4580 p->pixel = GET_PIXEL (ximg, x, y);
4581 if (rgb_p)
4582 x_query_colors (f, row, img->width);
4584 #else
4586 for (x = 0; x < img->width; ++x, ++p)
4588 /* W32_TODO: palette support needed here? */
4589 p->pixel = GET_PIXEL (ximg, x, y);
4590 if (rgb_p)
4592 p->red = RED16_FROM_ULONG (p->pixel);
4593 p->green = GREEN16_FROM_ULONG (p->pixel);
4594 p->blue = BLUE16_FROM_ULONG (p->pixel);
4597 #endif /* HAVE_X_WINDOWS */
4600 image_unget_x_image_or_dc (img, 0, ximg, prev);
4602 return colors;
4605 #ifdef HAVE_NTGUI
4607 /* Put a pixel of COLOR at position X, Y in XIMG. XIMG must have been
4608 created with CreateDIBSection, with the pointer to the bit values
4609 stored in ximg->data. */
4611 static void
4612 XPutPixel (XImagePtr ximg, int x, int y, COLORREF color)
4614 int width = ximg->info.bmiHeader.biWidth;
4615 unsigned char * pixel;
4617 /* True color images. */
4618 if (ximg->info.bmiHeader.biBitCount == 24)
4620 int rowbytes = width * 3;
4621 /* Ensure scanlines are aligned on 4 byte boundaries. */
4622 if (rowbytes % 4)
4623 rowbytes += 4 - (rowbytes % 4);
4625 pixel = ximg->data + y * rowbytes + x * 3;
4626 /* Windows bitmaps are in BGR order. */
4627 *pixel = GetBValue (color);
4628 *(pixel + 1) = GetGValue (color);
4629 *(pixel + 2) = GetRValue (color);
4631 /* Monochrome images. */
4632 else if (ximg->info.bmiHeader.biBitCount == 1)
4634 int rowbytes = width / 8;
4635 /* Ensure scanlines are aligned on 4 byte boundaries. */
4636 if (rowbytes % 4)
4637 rowbytes += 4 - (rowbytes % 4);
4638 pixel = ximg->data + y * rowbytes + x / 8;
4639 /* Filter out palette info. */
4640 if (color & 0x00ffffff)
4641 *pixel = *pixel | (1 << x % 8);
4642 else
4643 *pixel = *pixel & ~(1 << x % 8);
4645 else
4646 image_error ("XPutPixel: palette image not supported", Qnil, Qnil);
4649 #endif /* HAVE_NTGUI */
4651 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
4652 RGB members are set. F is the frame on which this all happens.
4653 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
4655 static void
4656 x_from_xcolors (struct frame *f, struct image *img, XColor *colors)
4658 int x, y;
4659 XImagePtr oimg = NULL;
4660 XColor *p;
4662 init_color_table ();
4664 x_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_COLORS);
4665 image_create_x_image_and_pixmap (f, img, img->width, img->height, 0,
4666 &oimg, 0);
4667 p = colors;
4668 for (y = 0; y < img->height; ++y)
4669 for (x = 0; x < img->width; ++x, ++p)
4671 unsigned long pixel;
4672 pixel = lookup_rgb_color (f, p->red, p->green, p->blue);
4673 XPutPixel (oimg, x, y, pixel);
4676 xfree (colors);
4678 image_put_x_image (f, img, oimg, 0);
4679 #ifdef COLOR_TABLE_SUPPORT
4680 img->colors = colors_in_color_table (&img->ncolors);
4681 free_color_table ();
4682 #endif /* COLOR_TABLE_SUPPORT */
4686 /* On frame F, perform edge-detection on image IMG.
4688 MATRIX is a nine-element array specifying the transformation
4689 matrix. See emboss_matrix for an example.
4691 COLOR_ADJUST is a color adjustment added to each pixel of the
4692 outgoing image. */
4694 static void
4695 x_detect_edges (struct frame *f, struct image *img, int *matrix, int color_adjust)
4697 XColor *colors = x_to_xcolors (f, img, 1);
4698 XColor *new, *p;
4699 int x, y, i, sum;
4701 for (i = sum = 0; i < 9; ++i)
4702 sum += eabs (matrix[i]);
4704 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
4706 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *new / img->width < img->height)
4707 memory_full (SIZE_MAX);
4708 new = xmalloc (sizeof *new * img->width * img->height);
4710 for (y = 0; y < img->height; ++y)
4712 p = COLOR (new, 0, y);
4713 p->red = p->green = p->blue = 0xffff/2;
4714 p = COLOR (new, img->width - 1, y);
4715 p->red = p->green = p->blue = 0xffff/2;
4718 for (x = 1; x < img->width - 1; ++x)
4720 p = COLOR (new, x, 0);
4721 p->red = p->green = p->blue = 0xffff/2;
4722 p = COLOR (new, x, img->height - 1);
4723 p->red = p->green = p->blue = 0xffff/2;
4726 for (y = 1; y < img->height - 1; ++y)
4728 p = COLOR (new, 1, y);
4730 for (x = 1; x < img->width - 1; ++x, ++p)
4732 int r, g, b, yy, xx;
4734 r = g = b = i = 0;
4735 for (yy = y - 1; yy < y + 2; ++yy)
4736 for (xx = x - 1; xx < x + 2; ++xx, ++i)
4737 if (matrix[i])
4739 XColor *t = COLOR (colors, xx, yy);
4740 r += matrix[i] * t->red;
4741 g += matrix[i] * t->green;
4742 b += matrix[i] * t->blue;
4745 r = (r / sum + color_adjust) & 0xffff;
4746 g = (g / sum + color_adjust) & 0xffff;
4747 b = (b / sum + color_adjust) & 0xffff;
4748 p->red = p->green = p->blue = COLOR_INTENSITY (r, g, b);
4752 xfree (colors);
4753 x_from_xcolors (f, img, new);
4755 #undef COLOR
4759 /* Perform the pre-defined `emboss' edge-detection on image IMG
4760 on frame F. */
4762 static void
4763 x_emboss (struct frame *f, struct image *img)
4765 x_detect_edges (f, img, emboss_matrix, 0xffff / 2);
4769 /* Transform image IMG which is used on frame F with a Laplace
4770 edge-detection algorithm. The result is an image that can be used
4771 to draw disabled buttons, for example. */
4773 static void
4774 x_laplace (struct frame *f, struct image *img)
4776 x_detect_edges (f, img, laplace_matrix, 45000);
4780 /* Perform edge-detection on image IMG on frame F, with specified
4781 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
4783 MATRIX must be either
4785 - a list of at least 9 numbers in row-major form
4786 - a vector of at least 9 numbers
4788 COLOR_ADJUST nil means use a default; otherwise it must be a
4789 number. */
4791 static void
4792 x_edge_detection (struct frame *f, struct image *img, Lisp_Object matrix,
4793 Lisp_Object color_adjust)
4795 int i = 0;
4796 int trans[9];
4798 if (CONSP (matrix))
4800 for (i = 0;
4801 i < 9 && CONSP (matrix) && NUMBERP (XCAR (matrix));
4802 ++i, matrix = XCDR (matrix))
4803 trans[i] = XFLOATINT (XCAR (matrix));
4805 else if (VECTORP (matrix) && ASIZE (matrix) >= 9)
4807 for (i = 0; i < 9 && NUMBERP (AREF (matrix, i)); ++i)
4808 trans[i] = XFLOATINT (AREF (matrix, i));
4811 if (NILP (color_adjust))
4812 color_adjust = make_number (0xffff / 2);
4814 if (i == 9 && NUMBERP (color_adjust))
4815 x_detect_edges (f, img, trans, XFLOATINT (color_adjust));
4819 /* Transform image IMG on frame F so that it looks disabled. */
4821 static void
4822 x_disable_image (struct frame *f, struct image *img)
4824 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
4825 #ifdef HAVE_NTGUI
4826 int n_planes = dpyinfo->n_planes * dpyinfo->n_cbits;
4827 #else
4828 int n_planes = dpyinfo->n_planes;
4829 #endif /* HAVE_NTGUI */
4831 if (n_planes >= 2)
4833 /* Color (or grayscale). Convert to gray, and equalize. Just
4834 drawing such images with a stipple can look very odd, so
4835 we're using this method instead. */
4836 XColor *colors = x_to_xcolors (f, img, 1);
4837 XColor *p, *end;
4838 const int h = 15000;
4839 const int l = 30000;
4841 for (p = colors, end = colors + img->width * img->height;
4842 p < end;
4843 ++p)
4845 int i = COLOR_INTENSITY (p->red, p->green, p->blue);
4846 int i2 = (0xffff - h - l) * i / 0xffff + l;
4847 p->red = p->green = p->blue = i2;
4850 x_from_xcolors (f, img, colors);
4853 /* Draw a cross over the disabled image, if we must or if we
4854 should. */
4855 if (n_planes < 2 || cross_disabled_images)
4857 #ifndef HAVE_NTGUI
4858 #ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
4860 #define MaskForeground(f) WHITE_PIX_DEFAULT (f)
4862 Display *dpy = FRAME_X_DISPLAY (f);
4863 GC gc;
4865 image_sync_to_pixmaps (f, img);
4866 gc = XCreateGC (dpy, img->pixmap, 0, NULL);
4867 XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f));
4868 XDrawLine (dpy, img->pixmap, gc, 0, 0,
4869 img->width - 1, img->height - 1);
4870 XDrawLine (dpy, img->pixmap, gc, 0, img->height - 1,
4871 img->width - 1, 0);
4872 XFreeGC (dpy, gc);
4874 if (img->mask)
4876 gc = XCreateGC (dpy, img->mask, 0, NULL);
4877 XSetForeground (dpy, gc, MaskForeground (f));
4878 XDrawLine (dpy, img->mask, gc, 0, 0,
4879 img->width - 1, img->height - 1);
4880 XDrawLine (dpy, img->mask, gc, 0, img->height - 1,
4881 img->width - 1, 0);
4882 XFreeGC (dpy, gc);
4884 #endif /* !HAVE_NS */
4885 #else
4886 HDC hdc, bmpdc;
4887 HGDIOBJ prev;
4889 hdc = get_frame_dc (f);
4890 bmpdc = CreateCompatibleDC (hdc);
4891 release_frame_dc (f, hdc);
4893 prev = SelectObject (bmpdc, img->pixmap);
4895 SetTextColor (bmpdc, BLACK_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 if (img->mask)
4903 SelectObject (bmpdc, img->mask);
4904 SetTextColor (bmpdc, WHITE_PIX_DEFAULT (f));
4905 MoveToEx (bmpdc, 0, 0, NULL);
4906 LineTo (bmpdc, img->width - 1, img->height - 1);
4907 MoveToEx (bmpdc, 0, img->height - 1, NULL);
4908 LineTo (bmpdc, img->width - 1, 0);
4910 SelectObject (bmpdc, prev);
4911 DeleteDC (bmpdc);
4912 #endif /* HAVE_NTGUI */
4917 /* Build a mask for image IMG which is used on frame F. FILE is the
4918 name of an image file, for error messages. HOW determines how to
4919 determine the background color of IMG. If it is a list '(R G B)',
4920 with R, G, and B being integers >= 0, take that as the color of the
4921 background. Otherwise, determine the background color of IMG
4922 heuristically. */
4924 static void
4925 x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how)
4927 XImagePtr_or_DC ximg;
4928 #ifndef HAVE_NTGUI
4929 XImagePtr mask_img;
4930 #else
4931 HGDIOBJ prev;
4932 char *mask_img;
4933 int row_width;
4934 #endif /* HAVE_NTGUI */
4935 int x, y;
4936 bool use_img_background;
4937 unsigned long bg = 0;
4939 if (img->mask)
4940 x_clear_image_1 (f, img, CLEAR_IMAGE_MASK);
4942 #ifndef HAVE_NTGUI
4943 #ifndef HAVE_NS
4944 /* Create an image and pixmap serving as mask. */
4945 if (! image_create_x_image_and_pixmap (f, img, img->width, img->height, 1,
4946 &mask_img, 1))
4947 return;
4948 #endif /* !HAVE_NS */
4949 #else
4950 /* Create the bit array serving as mask. */
4951 row_width = (img->width + 7) / 8;
4952 mask_img = xzalloc (row_width * img->height);
4953 #endif /* HAVE_NTGUI */
4955 /* Get the X image or create a memory device context for IMG. */
4956 ximg = image_get_x_image_or_dc (f, img, 0, &prev);
4958 /* Determine the background color of ximg. If HOW is `(R G B)'
4959 take that as color. Otherwise, use the image's background color. */
4960 use_img_background = 1;
4962 if (CONSP (how))
4964 int rgb[3], i;
4966 for (i = 0; i < 3 && CONSP (how) && NATNUMP (XCAR (how)); ++i)
4968 rgb[i] = XFASTINT (XCAR (how)) & 0xffff;
4969 how = XCDR (how);
4972 if (i == 3 && NILP (how))
4974 char color_name[30];
4975 sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]);
4976 bg = (
4977 #ifdef HAVE_NTGUI
4978 0x00ffffff & /* Filter out palette info. */
4979 #endif /* HAVE_NTGUI */
4980 x_alloc_image_color (f, img, build_string (color_name), 0));
4981 use_img_background = 0;
4985 if (use_img_background)
4986 bg = four_corners_best (ximg, img->corners, img->width, img->height);
4988 /* Set all bits in mask_img to 1 whose color in ximg is different
4989 from the background color bg. */
4990 #ifndef HAVE_NTGUI
4991 for (y = 0; y < img->height; ++y)
4992 for (x = 0; x < img->width; ++x)
4993 #ifndef HAVE_NS
4994 XPutPixel (mask_img, x, y, (XGetPixel (ximg, x, y) != bg
4995 ? PIX_MASK_DRAW : PIX_MASK_RETAIN));
4996 #else
4997 if (XGetPixel (ximg, x, y) == bg)
4998 ns_set_alpha (ximg, x, y, 0);
4999 #endif /* HAVE_NS */
5000 #ifndef HAVE_NS
5001 /* Fill in the background_transparent field while we have the mask handy. */
5002 image_background_transparent (img, f, mask_img);
5004 /* Put mask_img into the image. */
5005 image_put_x_image (f, img, mask_img, 1);
5006 #endif /* !HAVE_NS */
5007 #else
5008 for (y = 0; y < img->height; ++y)
5009 for (x = 0; x < img->width; ++x)
5011 COLORREF p = GetPixel (ximg, x, y);
5012 if (p != bg)
5013 mask_img[y * row_width + x / 8] |= 1 << (x % 8);
5016 /* Create the mask image. */
5017 img->mask = w32_create_pixmap_from_bitmap_data (img->width, img->height,
5018 mask_img);
5019 /* Fill in the background_transparent field while we have the mask handy. */
5020 SelectObject (ximg, img->mask);
5021 image_background_transparent (img, f, ximg);
5023 /* Was: x_destroy_x_image ((XImagePtr )mask_img); which seems bogus ++kfs */
5024 xfree (mask_img);
5025 #endif /* HAVE_NTGUI */
5027 image_unget_x_image_or_dc (img, 0, ximg, prev);
5031 /***********************************************************************
5032 PBM (mono, gray, color)
5033 ***********************************************************************/
5035 static bool pbm_image_p (Lisp_Object object);
5036 static bool pbm_load (struct frame *f, struct image *img);
5038 /* The symbol `pbm' identifying images of this type. */
5040 static Lisp_Object Qpbm;
5042 /* Indices of image specification fields in gs_format, below. */
5044 enum pbm_keyword_index
5046 PBM_TYPE,
5047 PBM_FILE,
5048 PBM_DATA,
5049 PBM_ASCENT,
5050 PBM_MARGIN,
5051 PBM_RELIEF,
5052 PBM_ALGORITHM,
5053 PBM_HEURISTIC_MASK,
5054 PBM_MASK,
5055 PBM_FOREGROUND,
5056 PBM_BACKGROUND,
5057 PBM_LAST
5060 /* Vector of image_keyword structures describing the format
5061 of valid user-defined image specifications. */
5063 static const struct image_keyword pbm_format[PBM_LAST] =
5065 {":type", IMAGE_SYMBOL_VALUE, 1},
5066 {":file", IMAGE_STRING_VALUE, 0},
5067 {":data", IMAGE_STRING_VALUE, 0},
5068 {":ascent", IMAGE_ASCENT_VALUE, 0},
5069 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
5070 {":relief", IMAGE_INTEGER_VALUE, 0},
5071 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5072 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5073 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5074 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
5075 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
5078 /* Structure describing the image type `pbm'. */
5080 static struct image_type pbm_type =
5082 &Qpbm,
5083 pbm_image_p,
5084 pbm_load,
5085 x_clear_image,
5086 NULL,
5087 NULL
5091 /* Return true if OBJECT is a valid PBM image specification. */
5093 static bool
5094 pbm_image_p (Lisp_Object object)
5096 struct image_keyword fmt[PBM_LAST];
5098 memcpy (fmt, pbm_format, sizeof fmt);
5100 if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm))
5101 return 0;
5103 /* Must specify either :data or :file. */
5104 return fmt[PBM_DATA].count + fmt[PBM_FILE].count == 1;
5108 /* Scan a decimal number from *S and return it. Advance *S while
5109 reading the number. END is the end of the string. Value is -1 at
5110 end of input. */
5112 static int
5113 pbm_scan_number (unsigned char **s, unsigned char *end)
5115 int c = 0, val = -1;
5117 while (*s < end)
5119 /* Skip white-space. */
5120 while (*s < end && (c = *(*s)++, c_isspace (c)))
5123 if (c == '#')
5125 /* Skip comment to end of line. */
5126 while (*s < end && (c = *(*s)++, c != '\n'))
5129 else if (c_isdigit (c))
5131 /* Read decimal number. */
5132 val = c - '0';
5133 while (*s < end && (c = *(*s)++, c_isdigit (c)))
5134 val = 10 * val + c - '0';
5135 break;
5137 else
5138 break;
5141 return val;
5145 /* Load PBM image IMG for use on frame F. */
5147 static bool
5148 pbm_load (struct frame *f, struct image *img)
5150 bool raw_p;
5151 int x, y;
5152 int width, height, max_color_idx = 0;
5153 XImagePtr ximg;
5154 Lisp_Object file, specified_file;
5155 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
5156 unsigned char *contents = NULL;
5157 unsigned char *end, *p;
5158 ptrdiff_t size;
5160 specified_file = image_spec_value (img->spec, QCfile, NULL);
5162 if (STRINGP (specified_file))
5164 file = x_find_image_file (specified_file);
5165 if (!STRINGP (file))
5167 image_error ("Cannot find image file `%s'", specified_file, Qnil);
5168 return 0;
5171 contents = slurp_file (SSDATA (file), &size);
5172 if (contents == NULL)
5174 image_error ("Error reading `%s'", file, Qnil);
5175 return 0;
5178 p = contents;
5179 end = contents + size;
5181 else
5183 Lisp_Object data;
5184 data = image_spec_value (img->spec, QCdata, NULL);
5185 if (!STRINGP (data))
5187 image_error ("Invalid image data `%s'", data, Qnil);
5188 return 0;
5190 p = SDATA (data);
5191 end = p + SBYTES (data);
5194 /* Check magic number. */
5195 if (end - p < 2 || *p++ != 'P')
5197 image_error ("Not a PBM image: `%s'", img->spec, Qnil);
5198 error:
5199 xfree (contents);
5200 return 0;
5203 switch (*p++)
5205 case '1':
5206 raw_p = 0, type = PBM_MONO;
5207 break;
5209 case '2':
5210 raw_p = 0, type = PBM_GRAY;
5211 break;
5213 case '3':
5214 raw_p = 0, type = PBM_COLOR;
5215 break;
5217 case '4':
5218 raw_p = 1, type = PBM_MONO;
5219 break;
5221 case '5':
5222 raw_p = 1, type = PBM_GRAY;
5223 break;
5225 case '6':
5226 raw_p = 1, type = PBM_COLOR;
5227 break;
5229 default:
5230 image_error ("Not a PBM image: `%s'", img->spec, Qnil);
5231 goto error;
5234 /* Read width, height, maximum color-component. Characters
5235 starting with `#' up to the end of a line are ignored. */
5236 width = pbm_scan_number (&p, end);
5237 height = pbm_scan_number (&p, end);
5239 if (type != PBM_MONO)
5241 max_color_idx = pbm_scan_number (&p, end);
5242 if (max_color_idx > 65535 || max_color_idx < 0)
5244 image_error ("Unsupported maximum PBM color value", Qnil, Qnil);
5245 goto error;
5249 if (!check_image_size (f, width, height))
5251 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
5252 goto error;
5255 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
5256 goto error;
5258 /* Initialize the color hash table. */
5259 init_color_table ();
5261 if (type == PBM_MONO)
5263 int c = 0, g;
5264 struct image_keyword fmt[PBM_LAST];
5265 unsigned long fg = FRAME_FOREGROUND_PIXEL (f);
5266 unsigned long bg = FRAME_BACKGROUND_PIXEL (f);
5268 /* Parse the image specification. */
5269 memcpy (fmt, pbm_format, sizeof fmt);
5270 parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm);
5272 /* Get foreground and background colors, maybe allocate colors. */
5273 if (fmt[PBM_FOREGROUND].count
5274 && STRINGP (fmt[PBM_FOREGROUND].value))
5275 fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg);
5276 if (fmt[PBM_BACKGROUND].count
5277 && STRINGP (fmt[PBM_BACKGROUND].value))
5279 bg = x_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg);
5280 img->background = bg;
5281 img->background_valid = 1;
5284 for (y = 0; y < height; ++y)
5285 for (x = 0; x < width; ++x)
5287 if (raw_p)
5289 if ((x & 7) == 0)
5291 if (p >= end)
5293 x_destroy_x_image (ximg);
5294 x_clear_image (f, img);
5295 image_error ("Invalid image size in image `%s'",
5296 img->spec, Qnil);
5297 goto error;
5299 c = *p++;
5301 g = c & 0x80;
5302 c <<= 1;
5304 else
5305 g = pbm_scan_number (&p, end);
5307 XPutPixel (ximg, x, y, g ? fg : bg);
5310 else
5312 int expected_size = height * width;
5313 if (max_color_idx > 255)
5314 expected_size *= 2;
5315 if (type == PBM_COLOR)
5316 expected_size *= 3;
5318 if (raw_p && p + expected_size > end)
5320 x_destroy_x_image (ximg);
5321 x_clear_image (f, img);
5322 image_error ("Invalid image size in image `%s'",
5323 img->spec, Qnil);
5324 goto error;
5327 for (y = 0; y < height; ++y)
5328 for (x = 0; x < width; ++x)
5330 int r, g, b;
5332 if (type == PBM_GRAY && raw_p)
5334 r = g = b = *p++;
5335 if (max_color_idx > 255)
5336 r = g = b = r * 256 + *p++;
5338 else if (type == PBM_GRAY)
5339 r = g = b = pbm_scan_number (&p, end);
5340 else if (raw_p)
5342 r = *p++;
5343 if (max_color_idx > 255)
5344 r = r * 256 + *p++;
5345 g = *p++;
5346 if (max_color_idx > 255)
5347 g = g * 256 + *p++;
5348 b = *p++;
5349 if (max_color_idx > 255)
5350 b = b * 256 + *p++;
5352 else
5354 r = pbm_scan_number (&p, end);
5355 g = pbm_scan_number (&p, end);
5356 b = pbm_scan_number (&p, end);
5359 if (r < 0 || g < 0 || b < 0)
5361 x_destroy_x_image (ximg);
5362 image_error ("Invalid pixel value in image `%s'",
5363 img->spec, Qnil);
5364 goto error;
5367 /* RGB values are now in the range 0..max_color_idx.
5368 Scale this to the range 0..0xffff supported by X. */
5369 r = (double) r * 65535 / max_color_idx;
5370 g = (double) g * 65535 / max_color_idx;
5371 b = (double) b * 65535 / max_color_idx;
5372 XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
5376 #ifdef COLOR_TABLE_SUPPORT
5377 /* Store in IMG->colors the colors allocated for the image, and
5378 free the color table. */
5379 img->colors = colors_in_color_table (&img->ncolors);
5380 free_color_table ();
5381 #endif /* COLOR_TABLE_SUPPORT */
5383 img->width = width;
5384 img->height = height;
5386 /* Maybe fill in the background field while we have ximg handy. */
5388 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
5389 /* Casting avoids a GCC warning. */
5390 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
5392 /* Put ximg into the image. */
5393 image_put_x_image (f, img, ximg, 0);
5395 /* X and W32 versions did it here, MAC version above. ++kfs
5396 img->width = width;
5397 img->height = height; */
5399 xfree (contents);
5400 return 1;
5404 /***********************************************************************
5406 ***********************************************************************/
5408 #if defined (HAVE_PNG) || defined (HAVE_NS)
5410 /* Function prototypes. */
5412 static bool png_image_p (Lisp_Object object);
5413 static bool png_load (struct frame *f, struct image *img);
5415 /* The symbol `png' identifying images of this type. */
5417 static Lisp_Object Qpng;
5419 /* Indices of image specification fields in png_format, below. */
5421 enum png_keyword_index
5423 PNG_TYPE,
5424 PNG_DATA,
5425 PNG_FILE,
5426 PNG_ASCENT,
5427 PNG_MARGIN,
5428 PNG_RELIEF,
5429 PNG_ALGORITHM,
5430 PNG_HEURISTIC_MASK,
5431 PNG_MASK,
5432 PNG_BACKGROUND,
5433 PNG_LAST
5436 /* Vector of image_keyword structures describing the format
5437 of valid user-defined image specifications. */
5439 static const struct image_keyword png_format[PNG_LAST] =
5441 {":type", IMAGE_SYMBOL_VALUE, 1},
5442 {":data", IMAGE_STRING_VALUE, 0},
5443 {":file", IMAGE_STRING_VALUE, 0},
5444 {":ascent", IMAGE_ASCENT_VALUE, 0},
5445 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
5446 {":relief", IMAGE_INTEGER_VALUE, 0},
5447 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5448 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5449 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5450 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
5453 #if defined HAVE_NTGUI && defined WINDOWSNT
5454 static bool init_png_functions (void);
5455 #else
5456 #define init_png_functions NULL
5457 #endif
5459 /* Structure describing the image type `png'. */
5461 static struct image_type png_type =
5463 &Qpng,
5464 png_image_p,
5465 png_load,
5466 x_clear_image,
5467 init_png_functions,
5468 NULL
5471 /* Return true if OBJECT is a valid PNG image specification. */
5473 static bool
5474 png_image_p (Lisp_Object object)
5476 struct image_keyword fmt[PNG_LAST];
5477 memcpy (fmt, png_format, sizeof fmt);
5479 if (!parse_image_spec (object, fmt, PNG_LAST, Qpng))
5480 return 0;
5482 /* Must specify either the :data or :file keyword. */
5483 return fmt[PNG_FILE].count + fmt[PNG_DATA].count == 1;
5486 #endif /* HAVE_PNG || HAVE_NS */
5489 #ifdef HAVE_PNG
5491 #ifdef WINDOWSNT
5492 /* PNG library details. */
5494 DEF_IMGLIB_FN (png_voidp, png_get_io_ptr, (png_structp));
5495 DEF_IMGLIB_FN (int, png_sig_cmp, (png_bytep, png_size_t, png_size_t));
5496 DEF_IMGLIB_FN (png_structp, png_create_read_struct, (png_const_charp, png_voidp,
5497 png_error_ptr, png_error_ptr));
5498 DEF_IMGLIB_FN (png_infop, png_create_info_struct, (png_structp));
5499 DEF_IMGLIB_FN (void, png_destroy_read_struct, (png_structpp, png_infopp, png_infopp));
5500 DEF_IMGLIB_FN (void, png_set_read_fn, (png_structp, png_voidp, png_rw_ptr));
5501 DEF_IMGLIB_FN (void, png_set_sig_bytes, (png_structp, int));
5502 DEF_IMGLIB_FN (void, png_read_info, (png_structp, png_infop));
5503 DEF_IMGLIB_FN (png_uint_32, png_get_IHDR, (png_structp, png_infop,
5504 png_uint_32 *, png_uint_32 *,
5505 int *, int *, int *, int *, int *));
5506 DEF_IMGLIB_FN (png_uint_32, png_get_valid, (png_structp, png_infop, png_uint_32));
5507 DEF_IMGLIB_FN (void, png_set_strip_16, (png_structp));
5508 DEF_IMGLIB_FN (void, png_set_expand, (png_structp));
5509 DEF_IMGLIB_FN (void, png_set_gray_to_rgb, (png_structp));
5510 DEF_IMGLIB_FN (void, png_set_background, (png_structp, png_color_16p,
5511 int, int, double));
5512 DEF_IMGLIB_FN (png_uint_32, png_get_bKGD, (png_structp, png_infop, png_color_16p *));
5513 DEF_IMGLIB_FN (void, png_read_update_info, (png_structp, png_infop));
5514 DEF_IMGLIB_FN (png_byte, png_get_channels, (png_structp, png_infop));
5515 DEF_IMGLIB_FN (png_size_t, png_get_rowbytes, (png_structp, png_infop));
5516 DEF_IMGLIB_FN (void, png_read_image, (png_structp, png_bytepp));
5517 DEF_IMGLIB_FN (void, png_read_end, (png_structp, png_infop));
5518 DEF_IMGLIB_FN (void, png_error, (png_structp, png_const_charp));
5520 #if (PNG_LIBPNG_VER >= 10500)
5521 DEF_IMGLIB_FN (void, png_longjmp, (png_structp, int));
5522 DEF_IMGLIB_FN (jmp_buf *, png_set_longjmp_fn, (png_structp, png_longjmp_ptr, size_t));
5523 #endif /* libpng version >= 1.5 */
5525 static bool
5526 init_png_functions (void)
5528 HMODULE library;
5530 if (!(library = w32_delayed_load (Qpng)))
5531 return 0;
5533 LOAD_IMGLIB_FN (library, png_get_io_ptr);
5534 LOAD_IMGLIB_FN (library, png_sig_cmp);
5535 LOAD_IMGLIB_FN (library, png_create_read_struct);
5536 LOAD_IMGLIB_FN (library, png_create_info_struct);
5537 LOAD_IMGLIB_FN (library, png_destroy_read_struct);
5538 LOAD_IMGLIB_FN (library, png_set_read_fn);
5539 LOAD_IMGLIB_FN (library, png_set_sig_bytes);
5540 LOAD_IMGLIB_FN (library, png_read_info);
5541 LOAD_IMGLIB_FN (library, png_get_IHDR);
5542 LOAD_IMGLIB_FN (library, png_get_valid);
5543 LOAD_IMGLIB_FN (library, png_set_strip_16);
5544 LOAD_IMGLIB_FN (library, png_set_expand);
5545 LOAD_IMGLIB_FN (library, png_set_gray_to_rgb);
5546 LOAD_IMGLIB_FN (library, png_set_background);
5547 LOAD_IMGLIB_FN (library, png_get_bKGD);
5548 LOAD_IMGLIB_FN (library, png_read_update_info);
5549 LOAD_IMGLIB_FN (library, png_get_channels);
5550 LOAD_IMGLIB_FN (library, png_get_rowbytes);
5551 LOAD_IMGLIB_FN (library, png_read_image);
5552 LOAD_IMGLIB_FN (library, png_read_end);
5553 LOAD_IMGLIB_FN (library, png_error);
5555 #if (PNG_LIBPNG_VER >= 10500)
5556 LOAD_IMGLIB_FN (library, png_longjmp);
5557 LOAD_IMGLIB_FN (library, png_set_longjmp_fn);
5558 #endif /* libpng version >= 1.5 */
5560 return 1;
5562 #else
5564 #define fn_png_get_io_ptr png_get_io_ptr
5565 #define fn_png_sig_cmp png_sig_cmp
5566 #define fn_png_create_read_struct png_create_read_struct
5567 #define fn_png_create_info_struct png_create_info_struct
5568 #define fn_png_destroy_read_struct png_destroy_read_struct
5569 #define fn_png_set_read_fn png_set_read_fn
5570 #define fn_png_set_sig_bytes png_set_sig_bytes
5571 #define fn_png_read_info png_read_info
5572 #define fn_png_get_IHDR png_get_IHDR
5573 #define fn_png_get_valid png_get_valid
5574 #define fn_png_set_strip_16 png_set_strip_16
5575 #define fn_png_set_expand png_set_expand
5576 #define fn_png_set_gray_to_rgb png_set_gray_to_rgb
5577 #define fn_png_set_background png_set_background
5578 #define fn_png_get_bKGD png_get_bKGD
5579 #define fn_png_read_update_info png_read_update_info
5580 #define fn_png_get_channels png_get_channels
5581 #define fn_png_get_rowbytes png_get_rowbytes
5582 #define fn_png_read_image png_read_image
5583 #define fn_png_read_end png_read_end
5584 #define fn_png_error png_error
5586 #if (PNG_LIBPNG_VER >= 10500)
5587 #define fn_png_longjmp png_longjmp
5588 #define fn_png_set_longjmp_fn png_set_longjmp_fn
5589 #endif /* libpng version >= 1.5 */
5591 #endif /* WINDOWSNT */
5593 /* Possibly inefficient/inexact substitutes for _setjmp and _longjmp.
5594 Do not use sys_setjmp, as PNG supports only jmp_buf. The _longjmp
5595 substitute may munge the signal mask, but that should be OK here.
5596 MinGW (MS-Windows) uses _setjmp and defines setjmp to _setjmp in
5597 the system header setjmp.h; don't mess up that. */
5598 #ifndef HAVE__SETJMP
5599 # define _setjmp(j) setjmp (j)
5600 # define _longjmp longjmp
5601 #endif
5603 #if (PNG_LIBPNG_VER < 10500)
5604 #define PNG_LONGJMP(ptr) (_longjmp ((ptr)->jmpbuf, 1))
5605 #define PNG_JMPBUF(ptr) ((ptr)->jmpbuf)
5606 #else
5607 /* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908) */
5608 #define PNG_LONGJMP(ptr) (fn_png_longjmp ((ptr), 1))
5609 #define PNG_JMPBUF(ptr) \
5610 (*fn_png_set_longjmp_fn ((ptr), _longjmp, sizeof (jmp_buf)))
5611 #endif
5613 /* Error and warning handlers installed when the PNG library
5614 is initialized. */
5616 static _Noreturn void
5617 my_png_error (png_struct *png_ptr, const char *msg)
5619 eassert (png_ptr != NULL);
5620 /* Avoid compiler warning about deprecated direct access to
5621 png_ptr's fields in libpng versions 1.4.x. */
5622 image_error ("PNG error: %s", build_string (msg), Qnil);
5623 PNG_LONGJMP (png_ptr);
5627 static void
5628 my_png_warning (png_struct *png_ptr, const char *msg)
5630 eassert (png_ptr != NULL);
5631 image_error ("PNG warning: %s", build_string (msg), Qnil);
5634 /* Memory source for PNG decoding. */
5636 struct png_memory_storage
5638 unsigned char *bytes; /* The data */
5639 ptrdiff_t len; /* How big is it? */
5640 ptrdiff_t index; /* Where are we? */
5644 /* Function set as reader function when reading PNG image from memory.
5645 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5646 bytes from the input to DATA. */
5648 static void
5649 png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length)
5651 struct png_memory_storage *tbr = fn_png_get_io_ptr (png_ptr);
5653 if (length > tbr->len - tbr->index)
5654 fn_png_error (png_ptr, "Read error");
5656 memcpy (data, tbr->bytes + tbr->index, length);
5657 tbr->index = tbr->index + length;
5661 /* Function set as reader function when reading PNG image from a file.
5662 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5663 bytes from the input to DATA. */
5665 static void
5666 png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length)
5668 FILE *fp = fn_png_get_io_ptr (png_ptr);
5670 if (fread (data, 1, length, fp) < length)
5671 fn_png_error (png_ptr, "Read error");
5675 /* Load PNG image IMG for use on frame F. Value is true if
5676 successful. */
5678 struct png_load_context
5680 /* These are members so that longjmp doesn't munge local variables. */
5681 png_struct *png_ptr;
5682 png_info *info_ptr;
5683 png_info *end_info;
5684 FILE *fp;
5685 png_byte *pixels;
5686 png_byte **rows;
5689 static bool
5690 png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5692 Lisp_Object file, specified_file;
5693 Lisp_Object specified_data;
5694 int x, y;
5695 ptrdiff_t i;
5696 XImagePtr ximg, mask_img = NULL;
5697 png_struct *png_ptr;
5698 png_info *info_ptr = NULL, *end_info = NULL;
5699 FILE *fp = NULL;
5700 png_byte sig[8];
5701 png_byte *pixels = NULL;
5702 png_byte **rows = NULL;
5703 png_uint_32 width, height;
5704 int bit_depth, color_type, interlace_type;
5705 png_byte channels;
5706 png_uint_32 row_bytes;
5707 bool transparent_p;
5708 struct png_memory_storage tbr; /* Data to be read */
5710 /* Find out what file to load. */
5711 specified_file = image_spec_value (img->spec, QCfile, NULL);
5712 specified_data = image_spec_value (img->spec, QCdata, NULL);
5714 if (NILP (specified_data))
5716 file = x_find_image_file (specified_file);
5717 if (!STRINGP (file))
5719 image_error ("Cannot find image file `%s'", specified_file, Qnil);
5720 return 0;
5723 /* Open the image file. */
5724 fp = emacs_fopen (SSDATA (file), "rb");
5725 if (!fp)
5727 image_error ("Cannot open image file `%s'", file, Qnil);
5728 return 0;
5731 /* Check PNG signature. */
5732 if (fread (sig, 1, sizeof sig, fp) != sizeof sig
5733 || fn_png_sig_cmp (sig, 0, sizeof sig))
5735 fclose (fp);
5736 image_error ("Not a PNG file: `%s'", file, Qnil);
5737 return 0;
5740 else
5742 if (!STRINGP (specified_data))
5744 image_error ("Invalid image data `%s'", specified_data, Qnil);
5745 return 0;
5748 /* Read from memory. */
5749 tbr.bytes = SDATA (specified_data);
5750 tbr.len = SBYTES (specified_data);
5751 tbr.index = 0;
5753 /* Check PNG signature. */
5754 if (tbr.len < sizeof sig
5755 || fn_png_sig_cmp (tbr.bytes, 0, sizeof sig))
5757 image_error ("Not a PNG image: `%s'", img->spec, Qnil);
5758 return 0;
5761 /* Need to skip past the signature. */
5762 tbr.bytes += sizeof (sig);
5765 /* Initialize read and info structs for PNG lib. */
5766 png_ptr = fn_png_create_read_struct (PNG_LIBPNG_VER_STRING,
5767 NULL, my_png_error,
5768 my_png_warning);
5769 if (png_ptr)
5771 info_ptr = fn_png_create_info_struct (png_ptr);
5772 end_info = fn_png_create_info_struct (png_ptr);
5775 c->png_ptr = png_ptr;
5776 c->info_ptr = info_ptr;
5777 c->end_info = end_info;
5778 c->fp = fp;
5779 c->pixels = pixels;
5780 c->rows = rows;
5782 if (! (info_ptr && end_info))
5784 fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
5785 png_ptr = 0;
5787 if (! png_ptr)
5789 if (fp) fclose (fp);
5790 return 0;
5793 /* Set error jump-back. We come back here when the PNG library
5794 detects an error. */
5795 if (_setjmp (PNG_JMPBUF (png_ptr)))
5797 error:
5798 if (c->png_ptr)
5799 fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
5800 xfree (c->pixels);
5801 xfree (c->rows);
5802 if (c->fp)
5803 fclose (c->fp);
5804 return 0;
5807 /* Silence a bogus diagnostic; see GCC bug 54561. */
5808 IF_LINT (fp = c->fp);
5810 /* Read image info. */
5811 if (!NILP (specified_data))
5812 fn_png_set_read_fn (png_ptr, &tbr, png_read_from_memory);
5813 else
5814 fn_png_set_read_fn (png_ptr, fp, png_read_from_file);
5816 fn_png_set_sig_bytes (png_ptr, sizeof sig);
5817 fn_png_read_info (png_ptr, info_ptr);
5818 fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
5819 &interlace_type, NULL, NULL);
5821 if (! (width <= INT_MAX && height <= INT_MAX
5822 && check_image_size (f, width, height)))
5824 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
5825 goto error;
5828 /* Create the X image and pixmap now, so that the work below can be
5829 omitted if the image is too large for X. */
5830 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
5831 goto error;
5833 /* If image contains simply transparency data, we prefer to
5834 construct a clipping mask. */
5835 if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
5836 transparent_p = 1;
5837 else
5838 transparent_p = 0;
5840 /* This function is easier to write if we only have to handle
5841 one data format: RGB or RGBA with 8 bits per channel. Let's
5842 transform other formats into that format. */
5844 /* Strip more than 8 bits per channel. */
5845 if (bit_depth == 16)
5846 fn_png_set_strip_16 (png_ptr);
5848 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
5849 if available. */
5850 fn_png_set_expand (png_ptr);
5852 /* Convert grayscale images to RGB. */
5853 if (color_type == PNG_COLOR_TYPE_GRAY
5854 || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
5855 fn_png_set_gray_to_rgb (png_ptr);
5857 /* Handle alpha channel by combining the image with a background
5858 color. Do this only if a real alpha channel is supplied. For
5859 simple transparency, we prefer a clipping mask. */
5860 if (!transparent_p)
5862 /* png_color_16 *image_bg; */
5863 Lisp_Object specified_bg
5864 = image_spec_value (img->spec, QCbackground, NULL);
5865 int shift = (bit_depth == 16) ? 0 : 8;
5867 if (STRINGP (specified_bg))
5868 /* The user specified `:background', use that. */
5870 XColor color;
5871 if (x_defined_color (f, SSDATA (specified_bg), &color, 0))
5873 png_color_16 user_bg;
5875 memset (&user_bg, 0, sizeof user_bg);
5876 user_bg.red = color.red >> shift;
5877 user_bg.green = color.green >> shift;
5878 user_bg.blue = color.blue >> shift;
5880 fn_png_set_background (png_ptr, &user_bg,
5881 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
5884 else
5886 /* We use the current frame background, ignoring any default
5887 background color set by the image. */
5888 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
5889 XColor color;
5890 png_color_16 frame_background;
5892 color.pixel = FRAME_BACKGROUND_PIXEL (f);
5893 x_query_color (f, &color);
5895 memset (&frame_background, 0, sizeof frame_background);
5896 frame_background.red = color.red >> shift;
5897 frame_background.green = color.green >> shift;
5898 frame_background.blue = color.blue >> shift;
5899 #endif /* HAVE_X_WINDOWS */
5901 fn_png_set_background (png_ptr, &frame_background,
5902 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
5906 /* Update info structure. */
5907 fn_png_read_update_info (png_ptr, info_ptr);
5909 /* Get number of channels. Valid values are 1 for grayscale images
5910 and images with a palette, 2 for grayscale images with transparency
5911 information (alpha channel), 3 for RGB images, and 4 for RGB
5912 images with alpha channel, i.e. RGBA. If conversions above were
5913 sufficient we should only have 3 or 4 channels here. */
5914 channels = fn_png_get_channels (png_ptr, info_ptr);
5915 eassert (channels == 3 || channels == 4);
5917 /* Number of bytes needed for one row of the image. */
5918 row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr);
5920 /* Allocate memory for the image. */
5921 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height
5922 || min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height < row_bytes)
5923 memory_full (SIZE_MAX);
5924 c->pixels = pixels = xmalloc (sizeof *pixels * row_bytes * height);
5925 c->rows = rows = xmalloc (height * sizeof *rows);
5926 for (i = 0; i < height; ++i)
5927 rows[i] = pixels + i * row_bytes;
5929 /* Read the entire image. */
5930 fn_png_read_image (png_ptr, rows);
5931 fn_png_read_end (png_ptr, info_ptr);
5932 if (fp)
5934 fclose (fp);
5935 c->fp = NULL;
5938 /* Create an image and pixmap serving as mask if the PNG image
5939 contains an alpha channel. */
5940 if (channels == 4
5941 && !transparent_p
5942 && !image_create_x_image_and_pixmap (f, img, width, height, 1,
5943 &mask_img, 1))
5945 x_destroy_x_image (ximg);
5946 x_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP);
5947 goto error;
5950 /* Fill the X image and mask from PNG data. */
5951 init_color_table ();
5953 for (y = 0; y < height; ++y)
5955 png_byte *p = rows[y];
5957 for (x = 0; x < width; ++x)
5959 int r, g, b;
5961 r = *p++ << 8;
5962 g = *p++ << 8;
5963 b = *p++ << 8;
5964 XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
5965 /* An alpha channel, aka mask channel, associates variable
5966 transparency with an image. Where other image formats
5967 support binary transparency---fully transparent or fully
5968 opaque---PNG allows up to 254 levels of partial transparency.
5969 The PNG library implements partial transparency by combining
5970 the image with a specified background color.
5972 I'm not sure how to handle this here nicely: because the
5973 background on which the image is displayed may change, for
5974 real alpha channel support, it would be necessary to create
5975 a new image for each possible background.
5977 What I'm doing now is that a mask is created if we have
5978 boolean transparency information. Otherwise I'm using
5979 the frame's background color to combine the image with. */
5981 if (channels == 4)
5983 if (mask_img)
5984 XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN);
5985 ++p;
5990 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
5991 /* Set IMG's background color from the PNG image, unless the user
5992 overrode it. */
5994 png_color_16 *bg;
5995 if (fn_png_get_bKGD (png_ptr, info_ptr, &bg))
5997 img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue);
5998 img->background_valid = 1;
6002 #ifdef COLOR_TABLE_SUPPORT
6003 /* Remember colors allocated for this image. */
6004 img->colors = colors_in_color_table (&img->ncolors);
6005 free_color_table ();
6006 #endif /* COLOR_TABLE_SUPPORT */
6008 /* Clean up. */
6009 fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
6010 xfree (rows);
6011 xfree (pixels);
6013 img->width = width;
6014 img->height = height;
6016 /* Maybe fill in the background field while we have ximg handy.
6017 Casting avoids a GCC warning. */
6018 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
6020 /* Put ximg into the image. */
6021 image_put_x_image (f, img, ximg, 0);
6023 /* Same for the mask. */
6024 if (mask_img)
6026 /* Fill in the background_transparent field while we have the
6027 mask handy. Casting avoids a GCC warning. */
6028 image_background_transparent (img, f, (XImagePtr_or_DC)mask_img);
6030 image_put_x_image (f, img, mask_img, 1);
6033 return 1;
6036 static bool
6037 png_load (struct frame *f, struct image *img)
6039 struct png_load_context c;
6040 return png_load_body (f, img, &c);
6043 #else /* HAVE_PNG */
6045 #ifdef HAVE_NS
6046 static bool
6047 png_load (struct frame *f, struct image *img)
6049 return ns_load_image (f, img,
6050 image_spec_value (img->spec, QCfile, NULL),
6051 image_spec_value (img->spec, QCdata, NULL));
6053 #endif /* HAVE_NS */
6056 #endif /* !HAVE_PNG */
6060 /***********************************************************************
6061 JPEG
6062 ***********************************************************************/
6064 #if defined (HAVE_JPEG) || defined (HAVE_NS)
6066 static bool jpeg_image_p (Lisp_Object object);
6067 static bool jpeg_load (struct frame *f, struct image *img);
6069 /* The symbol `jpeg' identifying images of this type. */
6071 static Lisp_Object Qjpeg;
6073 /* Indices of image specification fields in gs_format, below. */
6075 enum jpeg_keyword_index
6077 JPEG_TYPE,
6078 JPEG_DATA,
6079 JPEG_FILE,
6080 JPEG_ASCENT,
6081 JPEG_MARGIN,
6082 JPEG_RELIEF,
6083 JPEG_ALGORITHM,
6084 JPEG_HEURISTIC_MASK,
6085 JPEG_MASK,
6086 JPEG_BACKGROUND,
6087 JPEG_LAST
6090 /* Vector of image_keyword structures describing the format
6091 of valid user-defined image specifications. */
6093 static const struct image_keyword jpeg_format[JPEG_LAST] =
6095 {":type", IMAGE_SYMBOL_VALUE, 1},
6096 {":data", IMAGE_STRING_VALUE, 0},
6097 {":file", IMAGE_STRING_VALUE, 0},
6098 {":ascent", IMAGE_ASCENT_VALUE, 0},
6099 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
6100 {":relief", IMAGE_INTEGER_VALUE, 0},
6101 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6102 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6103 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6104 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
6107 #if defined HAVE_NTGUI && defined WINDOWSNT
6108 static bool init_jpeg_functions (void);
6109 #else
6110 #define init_jpeg_functions NULL
6111 #endif
6113 /* Structure describing the image type `jpeg'. */
6115 static struct image_type jpeg_type =
6117 &Qjpeg,
6118 jpeg_image_p,
6119 jpeg_load,
6120 x_clear_image,
6121 init_jpeg_functions,
6122 NULL
6125 /* Return true if OBJECT is a valid JPEG image specification. */
6127 static bool
6128 jpeg_image_p (Lisp_Object object)
6130 struct image_keyword fmt[JPEG_LAST];
6132 memcpy (fmt, jpeg_format, sizeof fmt);
6134 if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg))
6135 return 0;
6137 /* Must specify either the :data or :file keyword. */
6138 return fmt[JPEG_FILE].count + fmt[JPEG_DATA].count == 1;
6141 #endif /* HAVE_JPEG || HAVE_NS */
6143 #ifdef HAVE_JPEG
6145 /* Work around a warning about HAVE_STDLIB_H being redefined in
6146 jconfig.h. */
6147 #ifdef HAVE_STDLIB_H
6148 #undef HAVE_STDLIB_H
6149 #endif /* HAVE_STLIB_H */
6151 #if defined (HAVE_NTGUI) && !defined (__WIN32__)
6152 /* In older releases of the jpeg library, jpeglib.h will define boolean
6153 differently depending on __WIN32__, so make sure it is defined. */
6154 #define __WIN32__ 1
6155 #endif
6157 /* rpcndr.h (via windows.h) and jpeglib.h both define boolean types.
6158 Some versions of jpeglib try to detect whether rpcndr.h is loaded,
6159 using the Windows boolean type instead of the jpeglib boolean type
6160 if so. Cygwin jpeglib, however, doesn't try to detect whether its
6161 headers are included along with windows.h, so under Cygwin, jpeglib
6162 attempts to define a conflicting boolean type. Worse, forcing
6163 Cygwin jpeglib headers to use the Windows boolean type doesn't work
6164 because it created an ABI incompatibility between the
6165 already-compiled jpeg library and the header interface definition.
6167 The best we can do is to define jpeglib's boolean type to a
6168 different name. This name, jpeg_boolean, remains in effect through
6169 the rest of image.c.
6171 #if defined CYGWIN && defined HAVE_NTGUI
6172 #define boolean jpeg_boolean
6173 #endif
6174 #include <jpeglib.h>
6175 #include <jerror.h>
6177 #ifdef WINDOWSNT
6179 /* JPEG library details. */
6180 DEF_IMGLIB_FN (void, jpeg_CreateDecompress, (j_decompress_ptr, int, size_t));
6181 DEF_IMGLIB_FN (boolean, jpeg_start_decompress, (j_decompress_ptr));
6182 DEF_IMGLIB_FN (boolean, jpeg_finish_decompress, (j_decompress_ptr));
6183 DEF_IMGLIB_FN (void, jpeg_destroy_decompress, (j_decompress_ptr));
6184 DEF_IMGLIB_FN (int, jpeg_read_header, (j_decompress_ptr, boolean));
6185 DEF_IMGLIB_FN (JDIMENSION, jpeg_read_scanlines, (j_decompress_ptr, JSAMPARRAY, JDIMENSION));
6186 DEF_IMGLIB_FN (struct jpeg_error_mgr *, jpeg_std_error, (struct jpeg_error_mgr *));
6187 DEF_IMGLIB_FN (boolean, jpeg_resync_to_restart, (j_decompress_ptr, int));
6189 static bool
6190 init_jpeg_functions (void)
6192 HMODULE library;
6194 if (!(library = w32_delayed_load (Qjpeg)))
6195 return 0;
6197 LOAD_IMGLIB_FN (library, jpeg_finish_decompress);
6198 LOAD_IMGLIB_FN (library, jpeg_read_scanlines);
6199 LOAD_IMGLIB_FN (library, jpeg_start_decompress);
6200 LOAD_IMGLIB_FN (library, jpeg_read_header);
6201 LOAD_IMGLIB_FN (library, jpeg_CreateDecompress);
6202 LOAD_IMGLIB_FN (library, jpeg_destroy_decompress);
6203 LOAD_IMGLIB_FN (library, jpeg_std_error);
6204 LOAD_IMGLIB_FN (library, jpeg_resync_to_restart);
6205 return 1;
6208 /* Wrapper since we can't directly assign the function pointer
6209 to another function pointer that was declared more completely easily. */
6210 static boolean
6211 jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo, int desired)
6213 return fn_jpeg_resync_to_restart (cinfo, desired);
6216 #else
6218 #define fn_jpeg_CreateDecompress(a,b,c) jpeg_create_decompress (a)
6219 #define fn_jpeg_start_decompress jpeg_start_decompress
6220 #define fn_jpeg_finish_decompress jpeg_finish_decompress
6221 #define fn_jpeg_destroy_decompress jpeg_destroy_decompress
6222 #define fn_jpeg_read_header jpeg_read_header
6223 #define fn_jpeg_read_scanlines jpeg_read_scanlines
6224 #define fn_jpeg_std_error jpeg_std_error
6225 #define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart
6227 #endif /* WINDOWSNT */
6229 struct my_jpeg_error_mgr
6231 struct jpeg_error_mgr pub;
6232 sys_jmp_buf setjmp_buffer;
6234 /* The remaining members are so that longjmp doesn't munge local
6235 variables. */
6236 struct jpeg_decompress_struct cinfo;
6237 enum
6239 MY_JPEG_ERROR_EXIT,
6240 MY_JPEG_INVALID_IMAGE_SIZE,
6241 MY_JPEG_CANNOT_CREATE_X
6242 } failure_code;
6243 #ifdef lint
6244 FILE *fp;
6245 #endif
6249 static _Noreturn void
6250 my_error_exit (j_common_ptr cinfo)
6252 struct my_jpeg_error_mgr *mgr = (struct my_jpeg_error_mgr *) cinfo->err;
6253 mgr->failure_code = MY_JPEG_ERROR_EXIT;
6254 sys_longjmp (mgr->setjmp_buffer, 1);
6258 /* Init source method for JPEG data source manager. Called by
6259 jpeg_read_header() before any data is actually read. See
6260 libjpeg.doc from the JPEG lib distribution. */
6262 static void
6263 our_common_init_source (j_decompress_ptr cinfo)
6268 /* Method to terminate data source. Called by
6269 jpeg_finish_decompress() after all data has been processed. */
6271 static void
6272 our_common_term_source (j_decompress_ptr cinfo)
6277 /* Fill input buffer method for JPEG data source manager. Called
6278 whenever more data is needed. We read the whole image in one step,
6279 so this only adds a fake end of input marker at the end. */
6281 static JOCTET our_memory_buffer[2];
6283 static boolean
6284 our_memory_fill_input_buffer (j_decompress_ptr cinfo)
6286 /* Insert a fake EOI marker. */
6287 struct jpeg_source_mgr *src = cinfo->src;
6289 our_memory_buffer[0] = (JOCTET) 0xFF;
6290 our_memory_buffer[1] = (JOCTET) JPEG_EOI;
6292 src->next_input_byte = our_memory_buffer;
6293 src->bytes_in_buffer = 2;
6294 return 1;
6298 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6299 is the JPEG data source manager. */
6301 static void
6302 our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes)
6304 struct jpeg_source_mgr *src = cinfo->src;
6306 if (src)
6308 if (num_bytes > src->bytes_in_buffer)
6309 ERREXIT (cinfo, JERR_INPUT_EOF);
6311 src->bytes_in_buffer -= num_bytes;
6312 src->next_input_byte += num_bytes;
6317 /* Set up the JPEG lib for reading an image from DATA which contains
6318 LEN bytes. CINFO is the decompression info structure created for
6319 reading the image. */
6321 static void
6322 jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, ptrdiff_t len)
6324 struct jpeg_source_mgr *src = cinfo->src;
6326 if (! src)
6328 /* First time for this JPEG object? */
6329 src = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
6330 JPOOL_PERMANENT, sizeof *src);
6331 cinfo->src = src;
6332 src->next_input_byte = data;
6335 src->init_source = our_common_init_source;
6336 src->fill_input_buffer = our_memory_fill_input_buffer;
6337 src->skip_input_data = our_memory_skip_input_data;
6338 src->resync_to_restart = jpeg_resync_to_restart_wrapper; /* Use default method. */
6339 src->term_source = our_common_term_source;
6340 src->bytes_in_buffer = len;
6341 src->next_input_byte = data;
6345 struct jpeg_stdio_mgr
6347 struct jpeg_source_mgr mgr;
6348 boolean finished;
6349 FILE *file;
6350 JOCTET *buffer;
6354 /* Size of buffer to read JPEG from file.
6355 Not too big, as we want to use alloc_small. */
6356 #define JPEG_STDIO_BUFFER_SIZE 8192
6359 /* Fill input buffer method for JPEG data source manager. Called
6360 whenever more data is needed. The data is read from a FILE *. */
6362 static boolean
6363 our_stdio_fill_input_buffer (j_decompress_ptr cinfo)
6365 struct jpeg_stdio_mgr *src;
6367 src = (struct jpeg_stdio_mgr *) cinfo->src;
6368 if (!src->finished)
6370 ptrdiff_t bytes;
6372 bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file);
6373 if (bytes > 0)
6374 src->mgr.bytes_in_buffer = bytes;
6375 else
6377 WARNMS (cinfo, JWRN_JPEG_EOF);
6378 src->finished = 1;
6379 src->buffer[0] = (JOCTET) 0xFF;
6380 src->buffer[1] = (JOCTET) JPEG_EOI;
6381 src->mgr.bytes_in_buffer = 2;
6383 src->mgr.next_input_byte = src->buffer;
6386 return 1;
6390 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6391 is the JPEG data source manager. */
6393 static void
6394 our_stdio_skip_input_data (j_decompress_ptr cinfo, long int num_bytes)
6396 struct jpeg_stdio_mgr *src;
6397 src = (struct jpeg_stdio_mgr *) cinfo->src;
6399 while (num_bytes > 0 && !src->finished)
6401 if (num_bytes <= src->mgr.bytes_in_buffer)
6403 src->mgr.bytes_in_buffer -= num_bytes;
6404 src->mgr.next_input_byte += num_bytes;
6405 break;
6407 else
6409 num_bytes -= src->mgr.bytes_in_buffer;
6410 src->mgr.bytes_in_buffer = 0;
6411 src->mgr.next_input_byte = NULL;
6413 our_stdio_fill_input_buffer (cinfo);
6419 /* Set up the JPEG lib for reading an image from a FILE *.
6420 CINFO is the decompression info structure created for
6421 reading the image. */
6423 static void
6424 jpeg_file_src (j_decompress_ptr cinfo, FILE *fp)
6426 struct jpeg_stdio_mgr *src = (struct jpeg_stdio_mgr *) cinfo->src;
6428 if (! src)
6430 /* First time for this JPEG object? */
6431 src = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
6432 JPOOL_PERMANENT, sizeof *src);
6433 cinfo->src = (struct jpeg_source_mgr *) src;
6434 src->buffer = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
6435 JPOOL_PERMANENT,
6436 JPEG_STDIO_BUFFER_SIZE);
6439 src->file = fp;
6440 src->finished = 0;
6441 src->mgr.init_source = our_common_init_source;
6442 src->mgr.fill_input_buffer = our_stdio_fill_input_buffer;
6443 src->mgr.skip_input_data = our_stdio_skip_input_data;
6444 src->mgr.resync_to_restart = jpeg_resync_to_restart_wrapper; /* Use default method. */
6445 src->mgr.term_source = our_common_term_source;
6446 src->mgr.bytes_in_buffer = 0;
6447 src->mgr.next_input_byte = NULL;
6451 /* Load image IMG for use on frame F. Patterned after example.c
6452 from the JPEG lib. */
6454 static bool
6455 jpeg_load_body (struct frame *f, struct image *img,
6456 struct my_jpeg_error_mgr *mgr)
6458 Lisp_Object file, specified_file;
6459 Lisp_Object specified_data;
6460 FILE *fp = NULL;
6461 JSAMPARRAY buffer;
6462 int row_stride, x, y;
6463 XImagePtr ximg = NULL;
6464 unsigned long *colors;
6465 int width, height;
6467 /* Open the JPEG file. */
6468 specified_file = image_spec_value (img->spec, QCfile, NULL);
6469 specified_data = image_spec_value (img->spec, QCdata, NULL);
6471 if (NILP (specified_data))
6473 file = x_find_image_file (specified_file);
6474 if (!STRINGP (file))
6476 image_error ("Cannot find image file `%s'", specified_file, Qnil);
6477 return 0;
6480 fp = emacs_fopen (SSDATA (file), "rb");
6481 if (fp == NULL)
6483 image_error ("Cannot open `%s'", file, Qnil);
6484 return 0;
6487 else if (!STRINGP (specified_data))
6489 image_error ("Invalid image data `%s'", specified_data, Qnil);
6490 return 0;
6493 IF_LINT (mgr->fp = fp);
6495 /* Customize libjpeg's error handling to call my_error_exit when an
6496 error is detected. This function will perform a longjmp. */
6497 mgr->cinfo.err = fn_jpeg_std_error (&mgr->pub);
6498 mgr->pub.error_exit = my_error_exit;
6499 if (sys_setjmp (mgr->setjmp_buffer))
6501 switch (mgr->failure_code)
6503 case MY_JPEG_ERROR_EXIT:
6505 char buf[JMSG_LENGTH_MAX];
6506 mgr->cinfo.err->format_message ((j_common_ptr) &mgr->cinfo, buf);
6507 image_error ("Error reading JPEG image `%s': %s", img->spec,
6508 build_string (buf));
6509 break;
6512 case MY_JPEG_INVALID_IMAGE_SIZE:
6513 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
6514 break;
6516 case MY_JPEG_CANNOT_CREATE_X:
6517 break;
6520 /* Close the input file and destroy the JPEG object. */
6521 if (fp)
6522 fclose (fp);
6523 fn_jpeg_destroy_decompress (&mgr->cinfo);
6525 /* If we already have an XImage, free that. */
6526 x_destroy_x_image (ximg);
6528 /* Free pixmap and colors. */
6529 x_clear_image (f, img);
6530 return 0;
6533 /* Silence a bogus diagnostic; see GCC bug 54561. */
6534 IF_LINT (fp = mgr->fp);
6536 /* Create the JPEG decompression object. Let it read from fp.
6537 Read the JPEG image header. */
6538 fn_jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo);
6540 if (NILP (specified_data))
6541 jpeg_file_src (&mgr->cinfo, fp);
6542 else
6543 jpeg_memory_src (&mgr->cinfo, SDATA (specified_data),
6544 SBYTES (specified_data));
6546 fn_jpeg_read_header (&mgr->cinfo, 1);
6548 /* Customize decompression so that color quantization will be used.
6549 Start decompression. */
6550 mgr->cinfo.quantize_colors = 1;
6551 fn_jpeg_start_decompress (&mgr->cinfo);
6552 width = img->width = mgr->cinfo.output_width;
6553 height = img->height = mgr->cinfo.output_height;
6555 if (!check_image_size (f, width, height))
6557 mgr->failure_code = MY_JPEG_INVALID_IMAGE_SIZE;
6558 sys_longjmp (mgr->setjmp_buffer, 1);
6561 /* Create X image and pixmap. */
6562 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
6564 mgr->failure_code = MY_JPEG_CANNOT_CREATE_X;
6565 sys_longjmp (mgr->setjmp_buffer, 1);
6568 /* Allocate colors. When color quantization is used,
6569 mgr->cinfo.actual_number_of_colors has been set with the number of
6570 colors generated, and mgr->cinfo.colormap is a two-dimensional array
6571 of color indices in the range 0..mgr->cinfo.actual_number_of_colors.
6572 No more than 255 colors will be generated. */
6574 int i, ir, ig, ib;
6576 if (mgr->cinfo.out_color_components > 2)
6577 ir = 0, ig = 1, ib = 2;
6578 else if (mgr->cinfo.out_color_components > 1)
6579 ir = 0, ig = 1, ib = 0;
6580 else
6581 ir = 0, ig = 0, ib = 0;
6583 /* Use the color table mechanism because it handles colors that
6584 cannot be allocated nicely. Such colors will be replaced with
6585 a default color, and we don't have to care about which colors
6586 can be freed safely, and which can't. */
6587 init_color_table ();
6588 colors = alloca (mgr->cinfo.actual_number_of_colors * sizeof *colors);
6590 for (i = 0; i < mgr->cinfo.actual_number_of_colors; ++i)
6592 /* Multiply RGB values with 255 because X expects RGB values
6593 in the range 0..0xffff. */
6594 int r = mgr->cinfo.colormap[ir][i] << 8;
6595 int g = mgr->cinfo.colormap[ig][i] << 8;
6596 int b = mgr->cinfo.colormap[ib][i] << 8;
6597 colors[i] = lookup_rgb_color (f, r, g, b);
6600 #ifdef COLOR_TABLE_SUPPORT
6601 /* Remember those colors actually allocated. */
6602 img->colors = colors_in_color_table (&img->ncolors);
6603 free_color_table ();
6604 #endif /* COLOR_TABLE_SUPPORT */
6607 /* Read pixels. */
6608 row_stride = width * mgr->cinfo.output_components;
6609 buffer = mgr->cinfo.mem->alloc_sarray ((j_common_ptr) &mgr->cinfo,
6610 JPOOL_IMAGE, row_stride, 1);
6611 for (y = 0; y < height; ++y)
6613 fn_jpeg_read_scanlines (&mgr->cinfo, buffer, 1);
6614 for (x = 0; x < mgr->cinfo.output_width; ++x)
6615 XPutPixel (ximg, x, y, colors[buffer[0][x]]);
6618 /* Clean up. */
6619 fn_jpeg_finish_decompress (&mgr->cinfo);
6620 fn_jpeg_destroy_decompress (&mgr->cinfo);
6621 if (fp)
6622 fclose (fp);
6624 /* Maybe fill in the background field while we have ximg handy. */
6625 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
6626 /* Casting avoids a GCC warning. */
6627 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
6629 /* Put ximg into the image. */
6630 image_put_x_image (f, img, ximg, 0);
6631 return 1;
6634 static bool
6635 jpeg_load (struct frame *f, struct image *img)
6637 struct my_jpeg_error_mgr mgr;
6638 return jpeg_load_body (f, img, &mgr);
6641 #else /* HAVE_JPEG */
6643 #ifdef HAVE_NS
6644 static bool
6645 jpeg_load (struct frame *f, struct image *img)
6647 return ns_load_image (f, img,
6648 image_spec_value (img->spec, QCfile, NULL),
6649 image_spec_value (img->spec, QCdata, NULL));
6651 #endif /* HAVE_NS */
6653 #endif /* !HAVE_JPEG */
6657 /***********************************************************************
6658 TIFF
6659 ***********************************************************************/
6661 #if defined (HAVE_TIFF) || defined (HAVE_NS)
6663 static bool tiff_image_p (Lisp_Object object);
6664 static bool tiff_load (struct frame *f, struct image *img);
6666 /* The symbol `tiff' identifying images of this type. */
6668 static Lisp_Object Qtiff;
6670 /* Indices of image specification fields in tiff_format, below. */
6672 enum tiff_keyword_index
6674 TIFF_TYPE,
6675 TIFF_DATA,
6676 TIFF_FILE,
6677 TIFF_ASCENT,
6678 TIFF_MARGIN,
6679 TIFF_RELIEF,
6680 TIFF_ALGORITHM,
6681 TIFF_HEURISTIC_MASK,
6682 TIFF_MASK,
6683 TIFF_BACKGROUND,
6684 TIFF_INDEX,
6685 TIFF_LAST
6688 /* Vector of image_keyword structures describing the format
6689 of valid user-defined image specifications. */
6691 static const struct image_keyword tiff_format[TIFF_LAST] =
6693 {":type", IMAGE_SYMBOL_VALUE, 1},
6694 {":data", IMAGE_STRING_VALUE, 0},
6695 {":file", IMAGE_STRING_VALUE, 0},
6696 {":ascent", IMAGE_ASCENT_VALUE, 0},
6697 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
6698 {":relief", IMAGE_INTEGER_VALUE, 0},
6699 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6700 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6701 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6702 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
6703 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}
6706 #if defined HAVE_NTGUI && defined WINDOWSNT
6707 static bool init_tiff_functions (void);
6708 #else
6709 #define init_tiff_functions NULL
6710 #endif
6712 /* Structure describing the image type `tiff'. */
6714 static struct image_type tiff_type =
6716 &Qtiff,
6717 tiff_image_p,
6718 tiff_load,
6719 x_clear_image,
6720 init_tiff_functions,
6721 NULL
6724 /* Return true if OBJECT is a valid TIFF image specification. */
6726 static bool
6727 tiff_image_p (Lisp_Object object)
6729 struct image_keyword fmt[TIFF_LAST];
6730 memcpy (fmt, tiff_format, sizeof fmt);
6732 if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff))
6733 return 0;
6735 /* Must specify either the :data or :file keyword. */
6736 return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1;
6739 #endif /* HAVE_TIFF || HAVE_NS */
6741 #ifdef HAVE_TIFF
6743 #include <tiffio.h>
6745 #ifdef WINDOWSNT
6747 /* TIFF library details. */
6748 DEF_IMGLIB_FN (TIFFErrorHandler, TIFFSetErrorHandler, (TIFFErrorHandler));
6749 DEF_IMGLIB_FN (TIFFErrorHandler, TIFFSetWarningHandler, (TIFFErrorHandler));
6750 DEF_IMGLIB_FN (TIFF *, TIFFOpen, (const char *, const char *));
6751 DEF_IMGLIB_FN (TIFF *, TIFFClientOpen, (const char *, const char *, thandle_t,
6752 TIFFReadWriteProc, TIFFReadWriteProc,
6753 TIFFSeekProc, TIFFCloseProc, TIFFSizeProc,
6754 TIFFMapFileProc, TIFFUnmapFileProc));
6755 DEF_IMGLIB_FN (int, TIFFGetField, (TIFF *, ttag_t, ...));
6756 DEF_IMGLIB_FN (int, TIFFReadRGBAImage, (TIFF *, uint32, uint32, uint32 *, int));
6757 DEF_IMGLIB_FN (void, TIFFClose, (TIFF *));
6758 DEF_IMGLIB_FN (int, TIFFSetDirectory, (TIFF *, tdir_t));
6760 static bool
6761 init_tiff_functions (void)
6763 HMODULE library;
6765 if (!(library = w32_delayed_load (Qtiff)))
6766 return 0;
6768 LOAD_IMGLIB_FN (library, TIFFSetErrorHandler);
6769 LOAD_IMGLIB_FN (library, TIFFSetWarningHandler);
6770 LOAD_IMGLIB_FN (library, TIFFOpen);
6771 LOAD_IMGLIB_FN (library, TIFFClientOpen);
6772 LOAD_IMGLIB_FN (library, TIFFGetField);
6773 LOAD_IMGLIB_FN (library, TIFFReadRGBAImage);
6774 LOAD_IMGLIB_FN (library, TIFFClose);
6775 LOAD_IMGLIB_FN (library, TIFFSetDirectory);
6776 return 1;
6779 #else
6781 #define fn_TIFFSetErrorHandler TIFFSetErrorHandler
6782 #define fn_TIFFSetWarningHandler TIFFSetWarningHandler
6783 #define fn_TIFFOpen TIFFOpen
6784 #define fn_TIFFClientOpen TIFFClientOpen
6785 #define fn_TIFFGetField TIFFGetField
6786 #define fn_TIFFReadRGBAImage TIFFReadRGBAImage
6787 #define fn_TIFFClose TIFFClose
6788 #define fn_TIFFSetDirectory TIFFSetDirectory
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 fn_TIFFSetErrorHandler ((TIFFErrorHandler) tiff_error_handler);
6950 fn_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;
6962 /* Try to open the image file. */
6963 tiff = fn_TIFFOpen (SSDATA (file), "r");
6964 if (tiff == NULL)
6966 image_error ("Cannot open `%s'", file, Qnil);
6967 return 0;
6970 else
6972 if (!STRINGP (specified_data))
6974 image_error ("Invalid image data `%s'", specified_data, Qnil);
6975 return 0;
6978 /* Memory source! */
6979 memsrc.bytes = SDATA (specified_data);
6980 memsrc.len = SBYTES (specified_data);
6981 memsrc.index = 0;
6983 tiff = fn_TIFFClientOpen ("memory_source", "r", (thandle_t)&memsrc,
6984 tiff_read_from_memory,
6985 tiff_write_from_memory,
6986 tiff_seek_in_memory,
6987 tiff_close_memory,
6988 tiff_size_of_memory,
6989 tiff_mmap_memory,
6990 tiff_unmap_memory);
6992 if (!tiff)
6994 image_error ("Cannot open memory source for `%s'", img->spec, Qnil);
6995 return 0;
6999 image = image_spec_value (img->spec, QCindex, NULL);
7000 if (INTEGERP (image))
7002 EMACS_INT ino = XFASTINT (image);
7003 if (! (TYPE_MINIMUM (tdir_t) <= ino && ino <= TYPE_MAXIMUM (tdir_t)
7004 && fn_TIFFSetDirectory (tiff, ino)))
7006 image_error ("Invalid image number `%s' in image `%s'",
7007 image, img->spec);
7008 fn_TIFFClose (tiff);
7009 return 0;
7013 /* Get width and height of the image, and allocate a raster buffer
7014 of width x height 32-bit values. */
7015 fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
7016 fn_TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
7018 if (!check_image_size (f, width, height))
7020 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
7021 fn_TIFFClose (tiff);
7022 return 0;
7025 /* Create the X image and pixmap. */
7026 if (! (height <= min (PTRDIFF_MAX, SIZE_MAX) / sizeof *buf / width
7027 && image_create_x_image_and_pixmap (f, img, width, height, 0,
7028 &ximg, 0)))
7030 fn_TIFFClose (tiff);
7031 return 0;
7034 buf = xmalloc (sizeof *buf * width * height);
7036 rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
7038 /* Count the number of images in the file. */
7039 for (count = 1; fn_TIFFSetDirectory (tiff, count); count++)
7040 continue;
7042 if (count > 1)
7043 img->lisp_data = Fcons (Qcount,
7044 Fcons (make_number (count),
7045 img->lisp_data));
7047 fn_TIFFClose (tiff);
7048 if (!rc)
7050 image_error ("Error reading TIFF image `%s'", img->spec, Qnil);
7051 xfree (buf);
7052 return 0;
7055 /* Initialize the color table. */
7056 init_color_table ();
7058 /* Process the pixel raster. Origin is in the lower-left corner. */
7059 for (y = 0; y < height; ++y)
7061 uint32 *row = buf + y * width;
7063 for (x = 0; x < width; ++x)
7065 uint32 abgr = row[x];
7066 int r = TIFFGetR (abgr) << 8;
7067 int g = TIFFGetG (abgr) << 8;
7068 int b = TIFFGetB (abgr) << 8;
7069 XPutPixel (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b));
7073 #ifdef COLOR_TABLE_SUPPORT
7074 /* Remember the colors allocated for the image. Free the color table. */
7075 img->colors = colors_in_color_table (&img->ncolors);
7076 free_color_table ();
7077 #endif /* COLOR_TABLE_SUPPORT */
7079 img->width = width;
7080 img->height = height;
7082 /* Maybe fill in the background field while we have ximg handy. */
7083 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7084 /* Casting avoids a GCC warning on W32. */
7085 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
7087 /* Put ximg into the image. */
7088 image_put_x_image (f, img, ximg, 0);
7089 xfree (buf);
7091 return 1;
7094 #else /* HAVE_TIFF */
7096 #ifdef HAVE_NS
7097 static bool
7098 tiff_load (struct frame *f, struct image *img)
7100 return ns_load_image (f, img,
7101 image_spec_value (img->spec, QCfile, NULL),
7102 image_spec_value (img->spec, QCdata, NULL));
7104 #endif /* HAVE_NS */
7106 #endif /* !HAVE_TIFF */
7110 /***********************************************************************
7112 ***********************************************************************/
7114 #if defined (HAVE_GIF) || defined (HAVE_NS)
7116 static bool gif_image_p (Lisp_Object object);
7117 static bool gif_load (struct frame *f, struct image *img);
7118 static void gif_clear_image (struct frame *f, struct image *img);
7120 /* The symbol `gif' identifying images of this type. */
7122 static Lisp_Object Qgif;
7124 /* Indices of image specification fields in gif_format, below. */
7126 enum gif_keyword_index
7128 GIF_TYPE,
7129 GIF_DATA,
7130 GIF_FILE,
7131 GIF_ASCENT,
7132 GIF_MARGIN,
7133 GIF_RELIEF,
7134 GIF_ALGORITHM,
7135 GIF_HEURISTIC_MASK,
7136 GIF_MASK,
7137 GIF_IMAGE,
7138 GIF_BACKGROUND,
7139 GIF_LAST
7142 /* Vector of image_keyword structures describing the format
7143 of valid user-defined image specifications. */
7145 static const struct image_keyword gif_format[GIF_LAST] =
7147 {":type", IMAGE_SYMBOL_VALUE, 1},
7148 {":data", IMAGE_STRING_VALUE, 0},
7149 {":file", IMAGE_STRING_VALUE, 0},
7150 {":ascent", IMAGE_ASCENT_VALUE, 0},
7151 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
7152 {":relief", IMAGE_INTEGER_VALUE, 0},
7153 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7154 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7155 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7156 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
7157 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
7160 #if defined HAVE_NTGUI && defined WINDOWSNT
7161 static bool init_gif_functions (void);
7162 #else
7163 #define init_gif_functions NULL
7164 #endif
7166 /* Structure describing the image type `gif'. */
7168 static struct image_type gif_type =
7170 &Qgif,
7171 gif_image_p,
7172 gif_load,
7173 gif_clear_image,
7174 init_gif_functions,
7175 NULL
7178 /* Free X resources of GIF image IMG which is used on frame F. */
7180 static void
7181 gif_clear_image (struct frame *f, struct image *img)
7183 img->lisp_data = Qnil;
7184 x_clear_image (f, img);
7187 /* Return true if OBJECT is a valid GIF image specification. */
7189 static bool
7190 gif_image_p (Lisp_Object object)
7192 struct image_keyword fmt[GIF_LAST];
7193 memcpy (fmt, gif_format, sizeof fmt);
7195 if (!parse_image_spec (object, fmt, GIF_LAST, Qgif))
7196 return 0;
7198 /* Must specify either the :data or :file keyword. */
7199 return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1;
7202 #endif /* HAVE_GIF */
7204 #ifdef HAVE_GIF
7206 #if defined (HAVE_NTGUI)
7208 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
7209 Undefine before redefining to avoid a preprocessor warning. */
7210 #ifdef DrawText
7211 #undef DrawText
7212 #endif
7213 /* avoid conflict with QuickdrawText.h */
7214 #define DrawText gif_DrawText
7215 #include <gif_lib.h>
7216 #undef DrawText
7218 /* Giflib before 5.0 didn't define these macros (used only if HAVE_NTGUI). */
7219 #ifndef GIFLIB_MINOR
7220 #define GIFLIB_MINOR 0
7221 #endif
7222 #ifndef GIFLIB_RELEASE
7223 #define GIFLIB_RELEASE 0
7224 #endif
7226 #else /* HAVE_NTGUI */
7228 #include <gif_lib.h>
7230 #endif /* HAVE_NTGUI */
7232 /* Giflib before 5.0 didn't define these macros. */
7233 #ifndef GIFLIB_MAJOR
7234 #define GIFLIB_MAJOR 4
7235 #endif
7237 #ifdef WINDOWSNT
7239 /* GIF library details. */
7240 DEF_IMGLIB_FN (int, DGifCloseFile, (GifFileType *));
7241 DEF_IMGLIB_FN (int, DGifSlurp, (GifFileType *));
7242 #if GIFLIB_MAJOR < 5
7243 DEF_IMGLIB_FN (GifFileType *, DGifOpen, (void *, InputFunc));
7244 DEF_IMGLIB_FN (GifFileType *, DGifOpenFileName, (const char *));
7245 #else
7246 DEF_IMGLIB_FN (GifFileType *, DGifOpen, (void *, InputFunc, int *));
7247 DEF_IMGLIB_FN (GifFileType *, DGifOpenFileName, (const char *, int *));
7248 DEF_IMGLIB_FN (char *, GifErrorString, (int));
7249 #endif
7251 static bool
7252 init_gif_functions (void)
7254 HMODULE library;
7256 if (!(library = w32_delayed_load (Qgif)))
7257 return 0;
7259 LOAD_IMGLIB_FN (library, DGifCloseFile);
7260 LOAD_IMGLIB_FN (library, DGifSlurp);
7261 LOAD_IMGLIB_FN (library, DGifOpen);
7262 LOAD_IMGLIB_FN (library, DGifOpenFileName);
7263 #if GIFLIB_MAJOR >= 5
7264 LOAD_IMGLIB_FN (library, GifErrorString);
7265 #endif
7266 return 1;
7269 #else
7271 #define fn_DGifCloseFile DGifCloseFile
7272 #define fn_DGifSlurp DGifSlurp
7273 #define fn_DGifOpen DGifOpen
7274 #define fn_DGifOpenFileName DGifOpenFileName
7275 #if 5 <= GIFLIB_MAJOR
7276 # define fn_GifErrorString GifErrorString
7277 #endif
7279 #endif /* WINDOWSNT */
7281 /* Reading a GIF image from memory
7282 Based on the PNG memory stuff to a certain extent. */
7284 typedef struct
7286 unsigned char *bytes;
7287 ptrdiff_t len;
7288 ptrdiff_t index;
7290 gif_memory_source;
7292 /* Make the current memory source available to gif_read_from_memory.
7293 It's done this way because not all versions of libungif support
7294 a UserData field in the GifFileType structure. */
7295 static gif_memory_source *current_gif_memory_src;
7297 static int
7298 gif_read_from_memory (GifFileType *file, GifByteType *buf, int len)
7300 gif_memory_source *src = current_gif_memory_src;
7302 if (len > src->len - src->index)
7303 return -1;
7305 memcpy (buf, src->bytes + src->index, len);
7306 src->index += len;
7307 return len;
7311 /* Load GIF image IMG for use on frame F. Value is true if
7312 successful. */
7314 static const int interlace_start[] = {0, 4, 2, 1};
7315 static const int interlace_increment[] = {8, 8, 4, 2};
7317 #define GIF_LOCAL_DESCRIPTOR_EXTENSION 249
7319 static bool
7320 gif_load (struct frame *f, struct image *img)
7322 Lisp_Object file;
7323 int rc, width, height, x, y, i, j;
7324 XImagePtr ximg;
7325 ColorMapObject *gif_color_map;
7326 unsigned long pixel_colors[256];
7327 GifFileType *gif;
7328 gif_memory_source memsrc;
7329 Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL);
7330 Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
7331 Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL);
7332 unsigned long bgcolor = 0;
7333 EMACS_INT idx;
7334 #if GIFLIB_MAJOR >= 5
7335 int gif_err;
7336 #endif
7338 if (NILP (specified_data))
7340 file = x_find_image_file (specified_file);
7341 if (!STRINGP (file))
7343 image_error ("Cannot find image file `%s'", specified_file, Qnil);
7344 return 0;
7347 /* Open the GIF file. */
7348 #if GIFLIB_MAJOR < 5
7349 gif = fn_DGifOpenFileName (SSDATA (file));
7350 if (gif == NULL)
7352 image_error ("Cannot open `%s'", file, Qnil);
7353 return 0;
7355 #else
7356 gif = fn_DGifOpenFileName (SSDATA (file), &gif_err);
7357 if (gif == NULL)
7359 image_error ("Cannot open `%s': %s",
7360 file, build_string (fn_GifErrorString (gif_err)));
7361 return 0;
7363 #endif
7365 else
7367 if (!STRINGP (specified_data))
7369 image_error ("Invalid image data `%s'", specified_data, Qnil);
7370 return 0;
7373 /* Read from memory! */
7374 current_gif_memory_src = &memsrc;
7375 memsrc.bytes = SDATA (specified_data);
7376 memsrc.len = SBYTES (specified_data);
7377 memsrc.index = 0;
7379 #if GIFLIB_MAJOR < 5
7380 gif = fn_DGifOpen (&memsrc, gif_read_from_memory);
7381 if (!gif)
7383 image_error ("Cannot open memory source `%s'", img->spec, Qnil);
7384 return 0;
7386 #else
7387 gif = fn_DGifOpen (&memsrc, gif_read_from_memory, &gif_err);
7388 if (!gif)
7390 image_error ("Cannot open memory source `%s': %s",
7391 img->spec, build_string (fn_GifErrorString (gif_err)));
7392 return 0;
7394 #endif
7397 /* Before reading entire contents, check the declared image size. */
7398 if (!check_image_size (f, gif->SWidth, gif->SHeight))
7400 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
7401 fn_DGifCloseFile (gif);
7402 return 0;
7405 /* Read entire contents. */
7406 rc = fn_DGifSlurp (gif);
7407 if (rc == GIF_ERROR || gif->ImageCount <= 0)
7409 image_error ("Error reading `%s'", img->spec, Qnil);
7410 fn_DGifCloseFile (gif);
7411 return 0;
7414 /* Which sub-image are we to display? */
7416 Lisp_Object image_number = image_spec_value (img->spec, QCindex, NULL);
7417 idx = INTEGERP (image_number) ? XFASTINT (image_number) : 0;
7418 if (idx < 0 || idx >= gif->ImageCount)
7420 image_error ("Invalid image number `%s' in image `%s'",
7421 image_number, img->spec);
7422 fn_DGifCloseFile (gif);
7423 return 0;
7427 width = img->width = gif->SWidth;
7428 height = img->height = gif->SHeight;
7430 img->corners[TOP_CORNER] = gif->SavedImages[0].ImageDesc.Top;
7431 img->corners[LEFT_CORNER] = gif->SavedImages[0].ImageDesc.Left;
7432 img->corners[BOT_CORNER]
7433 = img->corners[TOP_CORNER] + gif->SavedImages[0].ImageDesc.Height;
7434 img->corners[RIGHT_CORNER]
7435 = img->corners[LEFT_CORNER] + gif->SavedImages[0].ImageDesc.Width;
7437 if (!check_image_size (f, width, height))
7439 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
7440 fn_DGifCloseFile (gif);
7441 return 0;
7444 /* Check that the selected subimages fit. It's not clear whether
7445 the GIF spec requires this, but Emacs can crash if they don't fit. */
7446 for (j = 0; j <= idx; ++j)
7448 struct SavedImage *subimage = gif->SavedImages + j;
7449 int subimg_width = subimage->ImageDesc.Width;
7450 int subimg_height = subimage->ImageDesc.Height;
7451 int subimg_top = subimage->ImageDesc.Top;
7452 int subimg_left = subimage->ImageDesc.Left;
7453 if (! (0 <= subimg_width && 0 <= subimg_height
7454 && 0 <= subimg_top && subimg_top <= height - subimg_height
7455 && 0 <= subimg_left && subimg_left <= width - subimg_width))
7457 image_error ("Subimage does not fit in image", Qnil, Qnil);
7458 fn_DGifCloseFile (gif);
7459 return 0;
7463 /* Create the X image and pixmap. */
7464 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
7466 fn_DGifCloseFile (gif);
7467 return 0;
7470 /* Clear the part of the screen image not covered by the image.
7471 Full animated GIF support requires more here (see the gif89 spec,
7472 disposal methods). Let's simply assume that the part not covered
7473 by a sub-image is in the frame's background color. */
7474 for (y = 0; y < img->corners[TOP_CORNER]; ++y)
7475 for (x = 0; x < width; ++x)
7476 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7478 for (y = img->corners[BOT_CORNER]; y < height; ++y)
7479 for (x = 0; x < width; ++x)
7480 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7482 for (y = img->corners[TOP_CORNER]; y < img->corners[BOT_CORNER]; ++y)
7484 for (x = 0; x < img->corners[LEFT_CORNER]; ++x)
7485 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7486 for (x = img->corners[RIGHT_CORNER]; x < width; ++x)
7487 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7490 /* Read the GIF image into the X image. */
7492 /* FIXME: With the current implementation, loading an animated gif
7493 is quadratic in the number of animation frames, since each frame
7494 is a separate struct image. We must provide a way for a single
7495 gif_load call to construct and save all animation frames. */
7497 init_color_table ();
7498 if (STRINGP (specified_bg))
7499 bgcolor = x_alloc_image_color (f, img, specified_bg,
7500 FRAME_BACKGROUND_PIXEL (f));
7501 for (j = 0; j <= idx; ++j)
7503 /* We use a local variable `raster' here because RasterBits is a
7504 char *, which invites problems with bytes >= 0x80. */
7505 struct SavedImage *subimage = gif->SavedImages + j;
7506 unsigned char *raster = (unsigned char *) subimage->RasterBits;
7507 int transparency_color_index = -1;
7508 int disposal = 0;
7509 int subimg_width = subimage->ImageDesc.Width;
7510 int subimg_height = subimage->ImageDesc.Height;
7511 int subimg_top = subimage->ImageDesc.Top;
7512 int subimg_left = subimage->ImageDesc.Left;
7514 /* Find the Graphic Control Extension block for this sub-image.
7515 Extract the disposal method and transparency color. */
7516 for (i = 0; i < subimage->ExtensionBlockCount; i++)
7518 ExtensionBlock *extblock = subimage->ExtensionBlocks + i;
7520 if ((extblock->Function == GIF_LOCAL_DESCRIPTOR_EXTENSION)
7521 && extblock->ByteCount == 4
7522 && extblock->Bytes[0] & 1)
7524 /* From gif89a spec: 1 = "keep in place", 2 = "restore
7525 to background". Treat any other value like 2. */
7526 disposal = (extblock->Bytes[0] >> 2) & 7;
7527 transparency_color_index = (unsigned char) extblock->Bytes[3];
7528 break;
7532 /* We can't "keep in place" the first subimage. */
7533 if (j == 0)
7534 disposal = 2;
7536 /* For disposal == 0, the spec says "No disposal specified. The
7537 decoder is not required to take any action." In practice, it
7538 seems we need to treat this like "keep in place", see e.g.
7539 http://upload.wikimedia.org/wikipedia/commons/3/37/Clock.gif */
7540 if (disposal == 0)
7541 disposal = 1;
7543 /* Allocate subimage colors. */
7544 memset (pixel_colors, 0, sizeof pixel_colors);
7545 gif_color_map = subimage->ImageDesc.ColorMap;
7546 if (!gif_color_map)
7547 gif_color_map = gif->SColorMap;
7549 if (gif_color_map)
7550 for (i = 0; i < gif_color_map->ColorCount; ++i)
7552 if (transparency_color_index == i)
7553 pixel_colors[i] = STRINGP (specified_bg)
7554 ? bgcolor : FRAME_BACKGROUND_PIXEL (f);
7555 else
7557 int r = gif_color_map->Colors[i].Red << 8;
7558 int g = gif_color_map->Colors[i].Green << 8;
7559 int b = gif_color_map->Colors[i].Blue << 8;
7560 pixel_colors[i] = lookup_rgb_color (f, r, g, b);
7564 /* Apply the pixel values. */
7565 if (gif->SavedImages[j].ImageDesc.Interlace)
7567 int row, pass;
7569 for (y = 0, row = interlace_start[0], pass = 0;
7570 y < subimg_height;
7571 y++, row += interlace_increment[pass])
7573 while (subimg_height <= row)
7574 row = interlace_start[++pass];
7576 for (x = 0; x < subimg_width; x++)
7578 int c = raster[y * subimg_width + x];
7579 if (transparency_color_index != c || disposal != 1)
7580 XPutPixel (ximg, x + subimg_left, row + subimg_top,
7581 pixel_colors[c]);
7585 else
7587 for (y = 0; y < subimg_height; ++y)
7588 for (x = 0; x < subimg_width; ++x)
7590 int c = raster[y * subimg_width + x];
7591 if (transparency_color_index != c || disposal != 1)
7592 XPutPixel (ximg, x + subimg_left, y + subimg_top,
7593 pixel_colors[c]);
7598 #ifdef COLOR_TABLE_SUPPORT
7599 img->colors = colors_in_color_table (&img->ncolors);
7600 free_color_table ();
7601 #endif /* COLOR_TABLE_SUPPORT */
7603 /* Save GIF image extension data for `image-metadata'.
7604 Format is (count IMAGES extension-data (FUNCTION "BYTES" ...)). */
7605 img->lisp_data = Qnil;
7606 if (gif->SavedImages[idx].ExtensionBlockCount > 0)
7608 int delay = 0;
7609 ExtensionBlock *ext = gif->SavedImages[idx].ExtensionBlocks;
7610 for (i = 0; i < gif->SavedImages[idx].ExtensionBlockCount; i++, ext++)
7611 /* Append (... FUNCTION "BYTES") */
7613 img->lisp_data
7614 = Fcons (make_number (ext->Function),
7615 Fcons (make_unibyte_string (ext->Bytes, ext->ByteCount),
7616 img->lisp_data));
7617 if (ext->Function == GIF_LOCAL_DESCRIPTOR_EXTENSION
7618 && ext->ByteCount == 4)
7620 delay = ext->Bytes[2] << CHAR_BIT;
7621 delay |= ext->Bytes[1];
7624 img->lisp_data = list2 (Qextension_data, img->lisp_data);
7625 if (delay)
7626 img->lisp_data
7627 = Fcons (Qdelay,
7628 Fcons (make_float (delay / 100.0),
7629 img->lisp_data));
7632 if (gif->ImageCount > 1)
7633 img->lisp_data = Fcons (Qcount,
7634 Fcons (make_number (gif->ImageCount),
7635 img->lisp_data));
7637 fn_DGifCloseFile (gif);
7639 /* Maybe fill in the background field while we have ximg handy. */
7640 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7641 /* Casting avoids a GCC warning. */
7642 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
7644 /* Put ximg into the image. */
7645 image_put_x_image (f, img, ximg, 0);
7647 return 1;
7650 #else /* !HAVE_GIF */
7652 #ifdef HAVE_NS
7653 static bool
7654 gif_load (struct frame *f, struct image *img)
7656 return ns_load_image (f, img,
7657 image_spec_value (img->spec, QCfile, NULL),
7658 image_spec_value (img->spec, QCdata, NULL));
7660 #endif /* HAVE_NS */
7662 #endif /* HAVE_GIF */
7665 #ifdef HAVE_IMAGEMAGICK
7667 /***********************************************************************
7668 ImageMagick
7669 ***********************************************************************/
7671 /* Scale an image size by returning SIZE / DIVISOR * MULTIPLIER,
7672 safely rounded and clipped to int range. */
7674 static int
7675 scale_image_size (int size, size_t divisor, size_t multiplier)
7677 if (divisor != 0)
7679 double s = size;
7680 double scaled = s * multiplier / divisor + 0.5;
7681 if (scaled < INT_MAX)
7682 return scaled;
7684 return INT_MAX;
7687 /* Compute the desired size of an image with native size WIDTH x HEIGHT.
7688 Use SPEC to deduce the size. Store the desired size into
7689 *D_WIDTH x *D_HEIGHT. Store -1 x -1 if the native size is OK. */
7690 static void
7691 compute_image_size (size_t width, size_t height,
7692 Lisp_Object spec,
7693 int *d_width, int *d_height)
7695 Lisp_Object value;
7696 int desired_width, desired_height;
7698 /* If width and/or height is set in the display spec assume we want
7699 to scale to those values. If either h or w is unspecified, the
7700 unspecified should be calculated from the specified to preserve
7701 aspect ratio. */
7702 value = image_spec_value (spec, QCwidth, NULL);
7703 desired_width = NATNUMP (value) ? min (XFASTINT (value), INT_MAX) : -1;
7704 value = image_spec_value (spec, QCheight, NULL);
7705 desired_height = NATNUMP (value) ? min (XFASTINT (value), INT_MAX) : -1;
7707 if (desired_width == -1)
7709 value = image_spec_value (spec, QCmax_width, NULL);
7710 if (NATNUMP (value))
7712 int max_width = min (XFASTINT (value), INT_MAX);
7713 if (max_width < width)
7715 /* The image is wider than :max-width. */
7716 desired_width = max_width;
7717 if (desired_height == -1)
7719 desired_height = scale_image_size (desired_width,
7720 width, height);
7721 value = image_spec_value (spec, QCmax_height, NULL);
7722 if (NATNUMP (value))
7724 int max_height = min (XFASTINT (value), INT_MAX);
7725 if (max_height < desired_height)
7727 desired_height = max_height;
7728 desired_width = scale_image_size (desired_height,
7729 height, width);
7737 if (desired_height == -1)
7739 value = image_spec_value (spec, QCmax_height, NULL);
7740 if (NATNUMP (value))
7742 int max_height = min (XFASTINT (value), INT_MAX);
7743 if (max_height < height)
7744 desired_height = max_height;
7748 if (desired_width != -1 && desired_height == -1)
7749 /* w known, calculate h. */
7750 desired_height = scale_image_size (desired_width, width, height);
7752 if (desired_width == -1 && desired_height != -1)
7753 /* h known, calculate w. */
7754 desired_width = scale_image_size (desired_height, height, width);
7756 *d_width = desired_width;
7757 *d_height = desired_height;
7760 static Lisp_Object Qimagemagick;
7762 static bool imagemagick_image_p (Lisp_Object);
7763 static bool imagemagick_load (struct frame *, struct image *);
7764 static void imagemagick_clear_image (struct frame *, struct image *);
7766 /* Indices of image specification fields in imagemagick_format. */
7768 enum imagemagick_keyword_index
7770 IMAGEMAGICK_TYPE,
7771 IMAGEMAGICK_DATA,
7772 IMAGEMAGICK_FILE,
7773 IMAGEMAGICK_ASCENT,
7774 IMAGEMAGICK_MARGIN,
7775 IMAGEMAGICK_RELIEF,
7776 IMAGEMAGICK_ALGORITHM,
7777 IMAGEMAGICK_HEURISTIC_MASK,
7778 IMAGEMAGICK_MASK,
7779 IMAGEMAGICK_BACKGROUND,
7780 IMAGEMAGICK_HEIGHT,
7781 IMAGEMAGICK_WIDTH,
7782 IMAGEMAGICK_MAX_HEIGHT,
7783 IMAGEMAGICK_MAX_WIDTH,
7784 IMAGEMAGICK_FORMAT,
7785 IMAGEMAGICK_ROTATION,
7786 IMAGEMAGICK_CROP,
7787 IMAGEMAGICK_LAST
7790 /* Vector of image_keyword structures describing the format
7791 of valid user-defined image specifications. */
7793 static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
7795 {":type", IMAGE_SYMBOL_VALUE, 1},
7796 {":data", IMAGE_STRING_VALUE, 0},
7797 {":file", IMAGE_STRING_VALUE, 0},
7798 {":ascent", IMAGE_ASCENT_VALUE, 0},
7799 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
7800 {":relief", IMAGE_INTEGER_VALUE, 0},
7801 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7802 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7803 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7804 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
7805 {":height", IMAGE_INTEGER_VALUE, 0},
7806 {":width", IMAGE_INTEGER_VALUE, 0},
7807 {":max-height", IMAGE_INTEGER_VALUE, 0},
7808 {":max-width", IMAGE_INTEGER_VALUE, 0},
7809 {":format", IMAGE_SYMBOL_VALUE, 0},
7810 {":rotation", IMAGE_NUMBER_VALUE, 0},
7811 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
7814 #if defined HAVE_NTGUI && defined WINDOWSNT
7815 static bool init_imagemagick_functions (void);
7816 #else
7817 #define init_imagemagick_functions NULL
7818 #endif
7820 /* Structure describing the image type for any image handled via
7821 ImageMagick. */
7823 static struct image_type imagemagick_type =
7825 &Qimagemagick,
7826 imagemagick_image_p,
7827 imagemagick_load,
7828 imagemagick_clear_image,
7829 init_imagemagick_functions,
7830 NULL
7833 /* Free X resources of imagemagick image IMG which is used on frame F. */
7835 static void
7836 imagemagick_clear_image (struct frame *f,
7837 struct image *img)
7839 x_clear_image (f, img);
7842 /* Return true if OBJECT is a valid IMAGEMAGICK image specification. Do
7843 this by calling parse_image_spec and supplying the keywords that
7844 identify the IMAGEMAGICK format. */
7846 static bool
7847 imagemagick_image_p (Lisp_Object object)
7849 struct image_keyword fmt[IMAGEMAGICK_LAST];
7850 memcpy (fmt, imagemagick_format, sizeof fmt);
7852 if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick))
7853 return 0;
7855 /* Must specify either the :data or :file keyword. */
7856 return fmt[IMAGEMAGICK_FILE].count + fmt[IMAGEMAGICK_DATA].count == 1;
7859 /* The GIF library also defines DrawRectangle, but its never used in Emacs.
7860 Therefore rename the function so it doesn't collide with ImageMagick. */
7861 #define DrawRectangle DrawRectangleGif
7862 #include <wand/MagickWand.h>
7864 /* ImageMagick 6.5.3 through 6.6.5 hid PixelGetMagickColor for some reason.
7865 Emacs seems to work fine with the hidden version, so unhide it. */
7866 #include <magick/version.h>
7867 #if 0x653 <= MagickLibVersion && MagickLibVersion <= 0x665
7868 extern WandExport void PixelGetMagickColor (const PixelWand *,
7869 MagickPixelPacket *);
7870 #endif
7872 /* Log ImageMagick error message.
7873 Useful when a ImageMagick function returns the status `MagickFalse'. */
7875 static void
7876 imagemagick_error (MagickWand *wand)
7878 char *description;
7879 ExceptionType severity;
7881 description = MagickGetException (wand, &severity);
7882 image_error ("ImageMagick error: %s",
7883 build_string (description),
7884 Qnil);
7885 description = (char *) MagickRelinquishMemory (description);
7888 /* Possibly give ImageMagick some extra help to determine the image
7889 type by supplying a "dummy" filename based on the Content-Type. */
7891 static char *
7892 imagemagick_filename_hint (Lisp_Object spec, char hint_buffer[MaxTextExtent])
7894 Lisp_Object symbol = intern ("image-format-suffixes");
7895 Lisp_Object val = find_symbol_value (symbol);
7896 Lisp_Object format;
7898 if (! CONSP (val))
7899 return NULL;
7901 format = image_spec_value (spec, intern (":format"), NULL);
7902 val = Fcar_safe (Fcdr_safe (Fassq (format, val)));
7903 if (! STRINGP (val))
7904 return NULL;
7906 /* It's OK to truncate the hint if it has MaxTextExtent or more bytes,
7907 as ImageMagick would ignore the extra bytes anyway. */
7908 snprintf (hint_buffer, MaxTextExtent, "/tmp/foo.%s", SSDATA (val));
7909 return hint_buffer;
7912 /* Animated images (e.g., GIF89a) are composed from one "master image"
7913 (which is the first one, and then there's a number of images that
7914 follow. If following images have non-transparent colors, these are
7915 composed "on top" of the master image. So, in general, one has to
7916 compute ann the preceding images to be able to display a particular
7917 sub-image.
7919 Computing all the preceding images is too slow, so we maintain a
7920 cache of previously computed images. We have to maintain a cache
7921 separate from the image cache, because the images may be scaled
7922 before display. */
7924 struct animation_cache
7926 MagickWand *wand;
7927 int index;
7928 struct timespec update_time;
7929 struct animation_cache *next;
7930 char signature[FLEXIBLE_ARRAY_MEMBER];
7933 static struct animation_cache *animation_cache = NULL;
7935 static struct animation_cache *
7936 imagemagick_create_cache (char *signature)
7938 struct animation_cache *cache
7939 = xmalloc (offsetof (struct animation_cache, signature)
7940 + strlen (signature) + 1);
7941 cache->wand = 0;
7942 cache->index = 0;
7943 cache->next = 0;
7944 strcpy (cache->signature, signature);
7945 return cache;
7948 /* Discard cached images that haven't been used for a minute. */
7949 static void
7950 imagemagick_prune_animation_cache (void)
7952 struct animation_cache **pcache = &animation_cache;
7953 struct timespec old = timespec_sub (current_timespec (),
7954 make_timespec (60, 0));
7956 while (*pcache)
7958 struct animation_cache *cache = *pcache;
7959 if (timespec_cmp (old, cache->update_time) <= 0)
7960 pcache = &cache->next;
7961 else
7963 if (cache->wand)
7964 DestroyMagickWand (cache->wand);
7965 *pcache = cache->next;
7966 xfree (cache);
7971 static struct animation_cache *
7972 imagemagick_get_animation_cache (MagickWand *wand)
7974 char *signature = MagickGetImageSignature (wand);
7975 struct animation_cache *cache;
7976 struct animation_cache **pcache = &animation_cache;
7978 imagemagick_prune_animation_cache ();
7980 while (1)
7982 cache = *pcache;
7983 if (! cache)
7985 *pcache = cache = imagemagick_create_cache (signature);
7986 break;
7988 if (strcmp (signature, cache->signature) == 0)
7989 break;
7990 pcache = &cache->next;
7993 DestroyString (signature);
7994 cache->update_time = current_timespec ();
7995 return cache;
7998 static MagickWand *
7999 imagemagick_compute_animated_image (MagickWand *super_wand, int ino)
8001 int i;
8002 MagickWand *composite_wand;
8003 size_t dest_width, dest_height;
8004 struct animation_cache *cache = imagemagick_get_animation_cache (super_wand);
8006 MagickSetIteratorIndex (super_wand, 0);
8008 if (ino == 0 || cache->wand == NULL || cache->index > ino)
8010 composite_wand = MagickGetImage (super_wand);
8011 if (cache->wand)
8012 DestroyMagickWand (cache->wand);
8014 else
8015 composite_wand = cache->wand;
8017 dest_width = MagickGetImageWidth (composite_wand);
8018 dest_height = MagickGetImageHeight (composite_wand);
8020 for (i = max (1, cache->index + 1); i <= ino; i++)
8022 MagickWand *sub_wand;
8023 PixelIterator *source_iterator, *dest_iterator;
8024 PixelWand **source, **dest;
8025 size_t source_width, source_height;
8026 ssize_t source_left, source_top;
8027 MagickPixelPacket pixel;
8028 DisposeType dispose;
8029 ptrdiff_t lines = 0;
8031 MagickSetIteratorIndex (super_wand, i);
8032 sub_wand = MagickGetImage (super_wand);
8034 MagickGetImagePage (sub_wand, &source_width, &source_height,
8035 &source_left, &source_top);
8037 /* This flag says how to handle transparent pixels. */
8038 dispose = MagickGetImageDispose (sub_wand);
8040 source_iterator = NewPixelIterator (sub_wand);
8041 if (! source_iterator)
8043 DestroyMagickWand (composite_wand);
8044 DestroyMagickWand (sub_wand);
8045 cache->wand = NULL;
8046 image_error ("Imagemagick pixel iterator creation failed",
8047 Qnil, Qnil);
8048 return NULL;
8051 dest_iterator = NewPixelIterator (composite_wand);
8052 if (! dest_iterator)
8054 DestroyMagickWand (composite_wand);
8055 DestroyMagickWand (sub_wand);
8056 DestroyPixelIterator (source_iterator);
8057 cache->wand = NULL;
8058 image_error ("Imagemagick pixel iterator creation failed",
8059 Qnil, Qnil);
8060 return NULL;
8063 /* The sub-image may not start at origin, so move the destination
8064 iterator to where the sub-image should start. */
8065 if (source_top > 0)
8067 PixelSetIteratorRow (dest_iterator, source_top);
8068 lines = source_top;
8071 while ((source = PixelGetNextIteratorRow (source_iterator, &source_width))
8072 != NULL)
8074 ptrdiff_t x;
8076 /* Sanity check. This shouldn't happen, but apparently
8077 does in some pictures. */
8078 if (++lines >= dest_height)
8079 break;
8081 dest = PixelGetNextIteratorRow (dest_iterator, &dest_width);
8082 for (x = 0; x < source_width; x++)
8084 /* Sanity check. This shouldn't happen, but apparently
8085 also does in some pictures. */
8086 if (x + source_left > dest_width)
8087 break;
8088 /* Normally we only copy over non-transparent pixels,
8089 but if the disposal method is "Background", then we
8090 copy over all pixels. */
8091 if (dispose == BackgroundDispose ||
8092 PixelGetAlpha (source[x]))
8094 PixelGetMagickColor (source[x], &pixel);
8095 PixelSetMagickColor (dest[x + source_left], &pixel);
8098 PixelSyncIterator (dest_iterator);
8101 DestroyPixelIterator (source_iterator);
8102 DestroyPixelIterator (dest_iterator);
8103 DestroyMagickWand (sub_wand);
8106 /* Cache a copy for the next iteration. The current wand will be
8107 destroyed by the caller. */
8108 cache->wand = CloneMagickWand (composite_wand);
8109 cache->index = ino;
8111 return composite_wand;
8115 /* Helper function for imagemagick_load, which does the actual loading
8116 given contents and size, apart from frame and image structures,
8117 passed from imagemagick_load. Uses librimagemagick to do most of
8118 the image processing.
8120 F is a pointer to the Emacs frame; IMG to the image structure to
8121 prepare; CONTENTS is the string containing the IMAGEMAGICK data to
8122 be parsed; SIZE is the number of bytes of data; and FILENAME is
8123 either the file name or the image data.
8125 Return true if successful. */
8127 static bool
8128 imagemagick_load_image (struct frame *f, struct image *img,
8129 unsigned char *contents, unsigned int size,
8130 char *filename)
8132 size_t width, height;
8133 MagickBooleanType status;
8134 XImagePtr ximg;
8135 int x, y;
8136 MagickWand *image_wand;
8137 PixelIterator *iterator;
8138 PixelWand **pixels, *bg_wand = NULL;
8139 MagickPixelPacket pixel;
8140 Lisp_Object image;
8141 Lisp_Object value;
8142 Lisp_Object crop;
8143 EMACS_INT ino;
8144 int desired_width, desired_height;
8145 double rotation;
8146 int pixelwidth;
8147 char hint_buffer[MaxTextExtent];
8148 char *filename_hint = NULL;
8150 /* Handle image index for image types who can contain more than one image.
8151 Interface :index is same as for GIF. First we "ping" the image to see how
8152 many sub-images it contains. Pinging is faster than loading the image to
8153 find out things about it. */
8155 /* Initialize the imagemagick environment. */
8156 MagickWandGenesis ();
8157 image = image_spec_value (img->spec, QCindex, NULL);
8158 ino = INTEGERP (image) ? XFASTINT (image) : 0;
8159 image_wand = NewMagickWand ();
8161 if (filename)
8162 status = MagickReadImage (image_wand, filename);
8163 else
8165 filename_hint = imagemagick_filename_hint (img->spec, hint_buffer);
8166 MagickSetFilename (image_wand, filename_hint);
8167 status = MagickReadImageBlob (image_wand, contents, size);
8170 if (status == MagickFalse)
8172 imagemagick_error (image_wand);
8173 DestroyMagickWand (image_wand);
8174 return 0;
8177 if (ino < 0 || ino >= MagickGetNumberImages (image_wand))
8179 image_error ("Invalid image number `%s' in image `%s'",
8180 image, img->spec);
8181 DestroyMagickWand (image_wand);
8182 return 0;
8185 if (MagickGetNumberImages (image_wand) > 1)
8186 img->lisp_data =
8187 Fcons (Qcount,
8188 Fcons (make_number (MagickGetNumberImages (image_wand)),
8189 img->lisp_data));
8191 /* If we have an animated image, get the new wand based on the
8192 "super-wand". */
8193 if (MagickGetNumberImages (image_wand) > 1)
8195 MagickWand *super_wand = image_wand;
8196 image_wand = imagemagick_compute_animated_image (super_wand, ino);
8197 if (! image_wand)
8198 image_wand = super_wand;
8199 else
8200 DestroyMagickWand (super_wand);
8203 /* Retrieve the frame's background color, for use later. */
8205 XColor bgcolor;
8206 Lisp_Object specified_bg;
8208 specified_bg = image_spec_value (img->spec, QCbackground, NULL);
8209 if (!STRINGP (specified_bg)
8210 || !x_defined_color (f, SSDATA (specified_bg), &bgcolor, 0))
8212 #ifndef HAVE_NS
8213 bgcolor.pixel = FRAME_BACKGROUND_PIXEL (f);
8214 x_query_color (f, &bgcolor);
8215 #else
8216 ns_query_color (FRAME_BACKGROUND_COLOR (f), &bgcolor, 1);
8217 #endif
8220 bg_wand = NewPixelWand ();
8221 PixelSetRed (bg_wand, (double) bgcolor.red / 65535);
8222 PixelSetGreen (bg_wand, (double) bgcolor.green / 65535);
8223 PixelSetBlue (bg_wand, (double) bgcolor.blue / 65535);
8226 compute_image_size (MagickGetImageWidth (image_wand),
8227 MagickGetImageHeight (image_wand),
8228 img->spec, &desired_width, &desired_height);
8230 if (desired_width != -1 && desired_height != -1)
8232 status = MagickScaleImage (image_wand, desired_width, desired_height);
8233 if (status == MagickFalse)
8235 image_error ("Imagemagick scale failed", Qnil, Qnil);
8236 imagemagick_error (image_wand);
8237 goto imagemagick_error;
8241 /* crop behaves similar to image slicing in Emacs but is more memory
8242 efficient. */
8243 crop = image_spec_value (img->spec, QCcrop, NULL);
8245 if (CONSP (crop) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop)))
8247 /* After some testing, it seems MagickCropImage is the fastest crop
8248 function in ImageMagick. This crop function seems to do less copying
8249 than the alternatives, but it still reads the entire image into memory
8250 before cropping, which is apparently difficult to avoid when using
8251 imagemagick. */
8252 size_t crop_width = XINT (XCAR (crop));
8253 crop = XCDR (crop);
8254 if (CONSP (crop) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop)))
8256 size_t crop_height = XINT (XCAR (crop));
8257 crop = XCDR (crop);
8258 if (CONSP (crop) && TYPE_RANGED_INTEGERP (ssize_t, XCAR (crop)))
8260 ssize_t crop_x = XINT (XCAR (crop));
8261 crop = XCDR (crop);
8262 if (CONSP (crop) && TYPE_RANGED_INTEGERP (ssize_t, XCAR (crop)))
8264 ssize_t crop_y = XINT (XCAR (crop));
8265 MagickCropImage (image_wand, crop_width, crop_height,
8266 crop_x, crop_y);
8272 /* Furthermore :rotation. we need background color and angle for
8273 rotation. */
8275 TODO background handling for rotation specified_bg =
8276 image_spec_value (img->spec, QCbackground, NULL); if (!STRINGP
8277 (specified_bg). */
8278 value = image_spec_value (img->spec, QCrotation, NULL);
8279 if (FLOATP (value))
8281 rotation = extract_float (value);
8282 status = MagickRotateImage (image_wand, bg_wand, rotation);
8283 if (status == MagickFalse)
8285 image_error ("Imagemagick image rotate failed", Qnil, Qnil);
8286 imagemagick_error (image_wand);
8287 goto imagemagick_error;
8291 /* Set the canvas background color to the frame or specified
8292 background, and flatten the image. Note: as of ImageMagick
8293 6.6.0, SVG image transparency is not handled properly
8294 (e.g. etc/images/splash.svg shows a white background always). */
8296 MagickWand *new_wand;
8297 MagickSetImageBackgroundColor (image_wand, bg_wand);
8298 #ifdef HAVE_MAGICKMERGEIMAGELAYERS
8299 new_wand = MagickMergeImageLayers (image_wand, MergeLayer);
8300 #else
8301 new_wand = MagickFlattenImages (image_wand);
8302 #endif
8303 DestroyMagickWand (image_wand);
8304 image_wand = new_wand;
8307 /* Finally we are done manipulating the image. Figure out the
8308 resulting width/height and transfer ownership to Emacs. */
8309 height = MagickGetImageHeight (image_wand);
8310 width = MagickGetImageWidth (image_wand);
8312 if (! (width <= INT_MAX && height <= INT_MAX
8313 && check_image_size (f, width, height)))
8315 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
8316 goto imagemagick_error;
8319 /* We can now get a valid pixel buffer from the imagemagick file, if all
8320 went ok. */
8322 init_color_table ();
8324 #if defined (HAVE_MAGICKEXPORTIMAGEPIXELS) && ! defined (HAVE_NS)
8325 if (imagemagick_render_type != 0)
8327 /* Magicexportimage is normally faster than pixelpushing. This
8328 method is also well tested. Some aspects of this method are
8329 ad-hoc and needs to be more researched. */
8330 int imagedepth = 24; /*MagickGetImageDepth(image_wand);*/
8331 const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP"; /*"RGBP";*/
8332 /* Try to create a x pixmap to hold the imagemagick pixmap. */
8333 if (!image_create_x_image_and_pixmap (f, img, width, height, imagedepth,
8334 &ximg, 0))
8336 #ifdef COLOR_TABLE_SUPPORT
8337 free_color_table ();
8338 #endif
8339 image_error ("Imagemagick X bitmap allocation failure", Qnil, Qnil);
8340 goto imagemagick_error;
8343 /* Oddly, the below code doesn't seem to work:*/
8344 /* switch(ximg->bitmap_unit){ */
8345 /* case 8: */
8346 /* pixelwidth=CharPixel; */
8347 /* break; */
8348 /* case 16: */
8349 /* pixelwidth=ShortPixel; */
8350 /* break; */
8351 /* case 32: */
8352 /* pixelwidth=LongPixel; */
8353 /* break; */
8354 /* } */
8356 Here im just guessing the format of the bitmap.
8357 happens to work fine for:
8358 - bw djvu images
8359 on rgb display.
8360 seems about 3 times as fast as pixel pushing(not carefully measured)
8362 pixelwidth = CharPixel; /*??? TODO figure out*/
8363 MagickExportImagePixels (image_wand, 0, 0, width, height,
8364 exportdepth, pixelwidth, ximg->data);
8366 else
8367 #endif /* HAVE_MAGICKEXPORTIMAGEPIXELS */
8369 size_t image_height;
8371 /* Try to create a x pixmap to hold the imagemagick pixmap. */
8372 if (!image_create_x_image_and_pixmap (f, img, width, height, 0,
8373 &ximg, 0))
8375 #ifdef COLOR_TABLE_SUPPORT
8376 free_color_table ();
8377 #endif
8378 image_error ("Imagemagick X bitmap allocation failure", Qnil, Qnil);
8379 goto imagemagick_error;
8382 /* Copy imagemagick image to x with primitive yet robust pixel
8383 pusher loop. This has been tested a lot with many different
8384 images. */
8386 /* Copy pixels from the imagemagick image structure to the x image map. */
8387 iterator = NewPixelIterator (image_wand);
8388 if (! iterator)
8390 #ifdef COLOR_TABLE_SUPPORT
8391 free_color_table ();
8392 #endif
8393 x_destroy_x_image (ximg);
8394 image_error ("Imagemagick pixel iterator creation failed",
8395 Qnil, Qnil);
8396 goto imagemagick_error;
8399 image_height = MagickGetImageHeight (image_wand);
8400 for (y = 0; y < image_height; y++)
8402 pixels = PixelGetNextIteratorRow (iterator, &width);
8403 if (! pixels)
8404 break;
8405 for (x = 0; x < (long) width; x++)
8407 PixelGetMagickColor (pixels[x], &pixel);
8408 XPutPixel (ximg, x, y,
8409 lookup_rgb_color (f,
8410 pixel.red,
8411 pixel.green,
8412 pixel.blue));
8415 DestroyPixelIterator (iterator);
8418 #ifdef COLOR_TABLE_SUPPORT
8419 /* Remember colors allocated for this image. */
8420 img->colors = colors_in_color_table (&img->ncolors);
8421 free_color_table ();
8422 #endif /* COLOR_TABLE_SUPPORT */
8424 img->width = width;
8425 img->height = height;
8427 /* Put ximg into the image. */
8428 image_put_x_image (f, img, ximg, 0);
8430 /* Final cleanup. image_wand should be the only resource left. */
8431 DestroyMagickWand (image_wand);
8432 if (bg_wand) DestroyPixelWand (bg_wand);
8434 /* `MagickWandTerminus' terminates the imagemagick environment. */
8435 MagickWandTerminus ();
8437 return 1;
8439 imagemagick_error:
8440 DestroyMagickWand (image_wand);
8441 if (bg_wand) DestroyPixelWand (bg_wand);
8443 MagickWandTerminus ();
8444 /* TODO more cleanup. */
8445 image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil);
8446 return 0;
8450 /* Load IMAGEMAGICK image IMG for use on frame F. Value is true if
8451 successful. this function will go into the imagemagick_type structure, and
8452 the prototype thus needs to be compatible with that structure. */
8454 static bool
8455 imagemagick_load (struct frame *f, struct image *img)
8457 bool success_p = 0;
8458 Lisp_Object file_name;
8460 /* If IMG->spec specifies a file name, create a non-file spec from it. */
8461 file_name = image_spec_value (img->spec, QCfile, NULL);
8462 if (STRINGP (file_name))
8464 Lisp_Object file;
8466 file = x_find_image_file (file_name);
8467 if (!STRINGP (file))
8469 image_error ("Cannot find image file `%s'", file_name, Qnil);
8470 return 0;
8472 success_p = imagemagick_load_image (f, img, 0, 0, SSDATA (file));
8474 /* Else its not a file, its a lisp object. Load the image from a
8475 lisp object rather than a file. */
8476 else
8478 Lisp_Object data;
8480 data = image_spec_value (img->spec, QCdata, NULL);
8481 if (!STRINGP (data))
8483 image_error ("Invalid image data `%s'", data, Qnil);
8484 return 0;
8486 success_p = imagemagick_load_image (f, img, SDATA (data),
8487 SBYTES (data), NULL);
8490 return success_p;
8493 DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
8494 doc: /* Return a list of image types supported by ImageMagick.
8495 Each entry in this list is a symbol named after an ImageMagick format
8496 tag. See the ImageMagick manual for a list of ImageMagick formats and
8497 their descriptions (http://www.imagemagick.org/script/formats.php).
8498 You can also try the shell command: `identify -list format'.
8500 Note that ImageMagick recognizes many file-types that Emacs does not
8501 recognize as images, such as C. See `imagemagick-types-enable'
8502 and `imagemagick-types-inhibit'. */)
8503 (void)
8505 Lisp_Object typelist = Qnil;
8506 size_t numf = 0;
8507 ExceptionInfo ex;
8508 char **imtypes;
8509 size_t i;
8510 Lisp_Object Qimagemagicktype;
8512 GetExceptionInfo(&ex);
8513 imtypes = GetMagickList ("*", &numf, &ex);
8514 DestroyExceptionInfo(&ex);
8516 for (i = 0; i < numf; i++)
8518 Qimagemagicktype = intern (imtypes[i]);
8519 typelist = Fcons (Qimagemagicktype, typelist);
8521 return Fnreverse (typelist);
8524 #endif /* defined (HAVE_IMAGEMAGICK) */
8528 /***********************************************************************
8530 ***********************************************************************/
8532 #if defined (HAVE_RSVG)
8534 /* Function prototypes. */
8536 static bool svg_image_p (Lisp_Object object);
8537 static bool svg_load (struct frame *f, struct image *img);
8539 static bool svg_load_image (struct frame *, struct image *,
8540 unsigned char *, ptrdiff_t);
8542 /* The symbol `svg' identifying images of this type. */
8544 static Lisp_Object Qsvg;
8546 /* Indices of image specification fields in svg_format, below. */
8548 enum svg_keyword_index
8550 SVG_TYPE,
8551 SVG_DATA,
8552 SVG_FILE,
8553 SVG_ASCENT,
8554 SVG_MARGIN,
8555 SVG_RELIEF,
8556 SVG_ALGORITHM,
8557 SVG_HEURISTIC_MASK,
8558 SVG_MASK,
8559 SVG_BACKGROUND,
8560 SVG_LAST
8563 /* Vector of image_keyword structures describing the format
8564 of valid user-defined image specifications. */
8566 static const struct image_keyword svg_format[SVG_LAST] =
8568 {":type", IMAGE_SYMBOL_VALUE, 1},
8569 {":data", IMAGE_STRING_VALUE, 0},
8570 {":file", IMAGE_STRING_VALUE, 0},
8571 {":ascent", IMAGE_ASCENT_VALUE, 0},
8572 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
8573 {":relief", IMAGE_INTEGER_VALUE, 0},
8574 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8575 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8576 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8577 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
8580 #if defined HAVE_NTGUI && defined WINDOWSNT
8581 static bool init_svg_functions (void);
8582 #else
8583 #define init_svg_functions NULL
8584 #endif
8586 /* Structure describing the image type `svg'. Its the same type of
8587 structure defined for all image formats, handled by emacs image
8588 functions. See struct image_type in dispextern.h. */
8590 static struct image_type svg_type =
8592 &Qsvg,
8593 svg_image_p,
8594 svg_load,
8595 x_clear_image,
8596 init_svg_functions,
8597 NULL
8601 /* Return true if OBJECT is a valid SVG image specification. Do
8602 this by calling parse_image_spec and supplying the keywords that
8603 identify the SVG format. */
8605 static bool
8606 svg_image_p (Lisp_Object object)
8608 struct image_keyword fmt[SVG_LAST];
8609 memcpy (fmt, svg_format, sizeof fmt);
8611 if (!parse_image_spec (object, fmt, SVG_LAST, Qsvg))
8612 return 0;
8614 /* Must specify either the :data or :file keyword. */
8615 return fmt[SVG_FILE].count + fmt[SVG_DATA].count == 1;
8618 #include <librsvg/rsvg.h>
8620 #ifdef WINDOWSNT
8622 /* SVG library functions. */
8623 DEF_IMGLIB_FN (RsvgHandle *, rsvg_handle_new, (void));
8624 DEF_IMGLIB_FN (void, rsvg_handle_get_dimensions, (RsvgHandle *, RsvgDimensionData *));
8625 DEF_IMGLIB_FN (gboolean, rsvg_handle_write, (RsvgHandle *, const guchar *, gsize, GError **));
8626 DEF_IMGLIB_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **));
8627 DEF_IMGLIB_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *));
8628 DEF_IMGLIB_FN (void *, rsvg_handle_set_size_callback, (RsvgHandle *, RsvgSizeFunc, gpointer, GDestroyNotify));
8630 DEF_IMGLIB_FN (int, gdk_pixbuf_get_width, (const GdkPixbuf *));
8631 DEF_IMGLIB_FN (int, gdk_pixbuf_get_height, (const GdkPixbuf *));
8632 DEF_IMGLIB_FN (guchar *, gdk_pixbuf_get_pixels, (const GdkPixbuf *));
8633 DEF_IMGLIB_FN (int, gdk_pixbuf_get_rowstride, (const GdkPixbuf *));
8634 DEF_IMGLIB_FN (GdkColorspace, gdk_pixbuf_get_colorspace, (const GdkPixbuf *));
8635 DEF_IMGLIB_FN (int, gdk_pixbuf_get_n_channels, (const GdkPixbuf *));
8636 DEF_IMGLIB_FN (gboolean, gdk_pixbuf_get_has_alpha, (const GdkPixbuf *));
8637 DEF_IMGLIB_FN (int, gdk_pixbuf_get_bits_per_sample, (const GdkPixbuf *));
8639 #if ! GLIB_CHECK_VERSION (2, 36, 0)
8640 DEF_IMGLIB_FN (void, g_type_init, (void));
8641 #endif
8642 DEF_IMGLIB_FN (void, g_object_unref, (gpointer));
8643 DEF_IMGLIB_FN (void, g_error_free, (GError *));
8645 Lisp_Object Qgdk_pixbuf, Qglib, Qgobject;
8647 static bool
8648 init_svg_functions (void)
8650 HMODULE library, gdklib, glib, gobject;
8652 if (!(glib = w32_delayed_load (Qglib))
8653 || !(gobject = w32_delayed_load (Qgobject))
8654 || !(gdklib = w32_delayed_load (Qgdk_pixbuf))
8655 || !(library = w32_delayed_load (Qsvg)))
8656 return 0;
8658 LOAD_IMGLIB_FN (library, rsvg_handle_new);
8659 LOAD_IMGLIB_FN (library, rsvg_handle_get_dimensions);
8660 LOAD_IMGLIB_FN (library, rsvg_handle_write);
8661 LOAD_IMGLIB_FN (library, rsvg_handle_close);
8662 LOAD_IMGLIB_FN (library, rsvg_handle_get_pixbuf);
8664 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_width);
8665 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_height);
8666 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_pixels);
8667 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_rowstride);
8668 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_colorspace);
8669 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_n_channels);
8670 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_has_alpha);
8671 LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_bits_per_sample);
8673 #if ! GLIB_CHECK_VERSION (2, 36, 0)
8674 LOAD_IMGLIB_FN (gobject, g_type_init);
8675 #endif
8676 LOAD_IMGLIB_FN (gobject, g_object_unref);
8677 LOAD_IMGLIB_FN (glib, g_error_free);
8679 return 1;
8682 #else
8683 /* The following aliases for library functions allow dynamic loading
8684 to be used on some platforms. */
8685 #define fn_rsvg_handle_new rsvg_handle_new
8686 #define fn_rsvg_handle_get_dimensions rsvg_handle_get_dimensions
8687 #define fn_rsvg_handle_write rsvg_handle_write
8688 #define fn_rsvg_handle_close rsvg_handle_close
8689 #define fn_rsvg_handle_get_pixbuf rsvg_handle_get_pixbuf
8691 #define fn_gdk_pixbuf_get_width gdk_pixbuf_get_width
8692 #define fn_gdk_pixbuf_get_height gdk_pixbuf_get_height
8693 #define fn_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels
8694 #define fn_gdk_pixbuf_get_rowstride gdk_pixbuf_get_rowstride
8695 #define fn_gdk_pixbuf_get_colorspace gdk_pixbuf_get_colorspace
8696 #define fn_gdk_pixbuf_get_n_channels gdk_pixbuf_get_n_channels
8697 #define fn_gdk_pixbuf_get_has_alpha gdk_pixbuf_get_has_alpha
8698 #define fn_gdk_pixbuf_get_bits_per_sample gdk_pixbuf_get_bits_per_sample
8700 #if ! GLIB_CHECK_VERSION (2, 36, 0)
8701 #define fn_g_type_init g_type_init
8702 #endif
8703 #define fn_g_object_unref g_object_unref
8704 #define fn_g_error_free g_error_free
8705 #endif /* !WINDOWSNT */
8707 /* Load SVG image IMG for use on frame F. Value is true if
8708 successful. */
8710 static bool
8711 svg_load (struct frame *f, struct image *img)
8713 bool success_p = 0;
8714 Lisp_Object file_name;
8716 /* If IMG->spec specifies a file name, create a non-file spec from it. */
8717 file_name = image_spec_value (img->spec, QCfile, NULL);
8718 if (STRINGP (file_name))
8720 Lisp_Object file;
8721 unsigned char *contents;
8722 ptrdiff_t size;
8724 file = x_find_image_file (file_name);
8725 if (!STRINGP (file))
8727 image_error ("Cannot find image file `%s'", file_name, Qnil);
8728 return 0;
8731 /* Read the entire file into memory. */
8732 contents = slurp_file (SSDATA (file), &size);
8733 if (contents == NULL)
8735 image_error ("Error loading SVG image `%s'", img->spec, Qnil);
8736 return 0;
8738 /* If the file was slurped into memory properly, parse it. */
8739 success_p = svg_load_image (f, img, contents, size);
8740 xfree (contents);
8742 /* Else its not a file, its a lisp object. Load the image from a
8743 lisp object rather than a file. */
8744 else
8746 Lisp_Object data;
8748 data = image_spec_value (img->spec, QCdata, NULL);
8749 if (!STRINGP (data))
8751 image_error ("Invalid image data `%s'", data, Qnil);
8752 return 0;
8754 success_p = svg_load_image (f, img, SDATA (data), SBYTES (data));
8757 return success_p;
8760 /* svg_load_image is a helper function for svg_load, which does the
8761 actual loading given contents and size, apart from frame and image
8762 structures, passed from svg_load.
8764 Uses librsvg to do most of the image processing.
8766 Returns true when successful. */
8767 static bool
8768 svg_load_image (struct frame *f, /* Pointer to emacs frame structure. */
8769 struct image *img, /* Pointer to emacs image structure. */
8770 unsigned char *contents, /* String containing the SVG XML data to be parsed. */
8771 ptrdiff_t size) /* Size of data in bytes. */
8773 RsvgHandle *rsvg_handle;
8774 RsvgDimensionData dimension_data;
8775 GError *err = NULL;
8776 GdkPixbuf *pixbuf;
8777 int width;
8778 int height;
8779 const guint8 *pixels;
8780 int rowstride;
8781 XImagePtr ximg;
8782 Lisp_Object specified_bg;
8783 XColor background;
8784 int x;
8785 int y;
8787 #if ! GLIB_CHECK_VERSION (2, 36, 0)
8788 /* g_type_init is a glib function that must be called prior to
8789 using gnome type library functions (obsolete since 2.36.0). */
8790 fn_g_type_init ();
8791 #endif
8793 /* Make a handle to a new rsvg object. */
8794 rsvg_handle = fn_rsvg_handle_new ();
8796 /* Parse the contents argument and fill in the rsvg_handle. */
8797 fn_rsvg_handle_write (rsvg_handle, contents, size, &err);
8798 if (err) goto rsvg_error;
8800 /* The parsing is complete, rsvg_handle is ready to used, close it
8801 for further writes. */
8802 fn_rsvg_handle_close (rsvg_handle, &err);
8803 if (err) goto rsvg_error;
8805 fn_rsvg_handle_get_dimensions (rsvg_handle, &dimension_data);
8806 if (! check_image_size (f, dimension_data.width, dimension_data.height))
8808 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
8809 goto rsvg_error;
8812 /* We can now get a valid pixel buffer from the svg file, if all
8813 went ok. */
8814 pixbuf = fn_rsvg_handle_get_pixbuf (rsvg_handle);
8815 if (!pixbuf) goto rsvg_error;
8816 fn_g_object_unref (rsvg_handle);
8818 /* Extract some meta data from the svg handle. */
8819 width = fn_gdk_pixbuf_get_width (pixbuf);
8820 height = fn_gdk_pixbuf_get_height (pixbuf);
8821 pixels = fn_gdk_pixbuf_get_pixels (pixbuf);
8822 rowstride = fn_gdk_pixbuf_get_rowstride (pixbuf);
8824 /* Validate the svg meta data. */
8825 eassert (fn_gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB);
8826 eassert (fn_gdk_pixbuf_get_n_channels (pixbuf) == 4);
8827 eassert (fn_gdk_pixbuf_get_has_alpha (pixbuf));
8828 eassert (fn_gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
8830 /* Try to create a x pixmap to hold the svg pixmap. */
8831 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
8833 fn_g_object_unref (pixbuf);
8834 return 0;
8837 init_color_table ();
8839 /* Handle alpha channel by combining the image with a background
8840 color. */
8841 specified_bg = image_spec_value (img->spec, QCbackground, NULL);
8842 if (!STRINGP (specified_bg)
8843 || !x_defined_color (f, SSDATA (specified_bg), &background, 0))
8845 #ifndef HAVE_NS
8846 background.pixel = FRAME_BACKGROUND_PIXEL (f);
8847 x_query_color (f, &background);
8848 #else
8849 ns_query_color (FRAME_BACKGROUND_COLOR (f), &background, 1);
8850 #endif
8853 /* SVG pixmaps specify transparency in the last byte, so right
8854 shift 8 bits to get rid of it, since emacs doesn't support
8855 transparency. */
8856 background.red >>= 8;
8857 background.green >>= 8;
8858 background.blue >>= 8;
8860 /* This loop handles opacity values, since Emacs assumes
8861 non-transparent images. Each pixel must be "flattened" by
8862 calculating the resulting color, given the transparency of the
8863 pixel, and the image background color. */
8864 for (y = 0; y < height; ++y)
8866 for (x = 0; x < width; ++x)
8868 int red;
8869 int green;
8870 int blue;
8871 int opacity;
8873 red = *pixels++;
8874 green = *pixels++;
8875 blue = *pixels++;
8876 opacity = *pixels++;
8878 red = ((red * opacity)
8879 + (background.red * ((1 << 8) - opacity)));
8880 green = ((green * opacity)
8881 + (background.green * ((1 << 8) - opacity)));
8882 blue = ((blue * opacity)
8883 + (background.blue * ((1 << 8) - opacity)));
8885 XPutPixel (ximg, x, y, lookup_rgb_color (f, red, green, blue));
8888 pixels += rowstride - 4 * width;
8891 #ifdef COLOR_TABLE_SUPPORT
8892 /* Remember colors allocated for this image. */
8893 img->colors = colors_in_color_table (&img->ncolors);
8894 free_color_table ();
8895 #endif /* COLOR_TABLE_SUPPORT */
8897 fn_g_object_unref (pixbuf);
8899 img->width = width;
8900 img->height = height;
8902 /* Maybe fill in the background field while we have ximg handy.
8903 Casting avoids a GCC warning. */
8904 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
8906 /* Put ximg into the image. */
8907 image_put_x_image (f, img, ximg, 0);
8909 return 1;
8911 rsvg_error:
8912 fn_g_object_unref (rsvg_handle);
8913 /* FIXME: Use error->message so the user knows what is the actual
8914 problem with the image. */
8915 image_error ("Error parsing SVG image `%s'", img->spec, Qnil);
8916 fn_g_error_free (err);
8917 return 0;
8920 #endif /* defined (HAVE_RSVG) */
8925 /***********************************************************************
8926 Ghostscript
8927 ***********************************************************************/
8929 #ifdef HAVE_X_WINDOWS
8930 #define HAVE_GHOSTSCRIPT 1
8931 #endif /* HAVE_X_WINDOWS */
8933 #ifdef HAVE_GHOSTSCRIPT
8935 static bool gs_image_p (Lisp_Object object);
8936 static bool gs_load (struct frame *f, struct image *img);
8937 static void gs_clear_image (struct frame *f, struct image *img);
8939 /* Keyword symbols. */
8941 static Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height;
8943 /* Indices of image specification fields in gs_format, below. */
8945 enum gs_keyword_index
8947 GS_TYPE,
8948 GS_PT_WIDTH,
8949 GS_PT_HEIGHT,
8950 GS_FILE,
8951 GS_LOADER,
8952 GS_BOUNDING_BOX,
8953 GS_ASCENT,
8954 GS_MARGIN,
8955 GS_RELIEF,
8956 GS_ALGORITHM,
8957 GS_HEURISTIC_MASK,
8958 GS_MASK,
8959 GS_BACKGROUND,
8960 GS_LAST
8963 /* Vector of image_keyword structures describing the format
8964 of valid user-defined image specifications. */
8966 static const struct image_keyword gs_format[GS_LAST] =
8968 {":type", IMAGE_SYMBOL_VALUE, 1},
8969 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE, 1},
8970 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE, 1},
8971 {":file", IMAGE_STRING_VALUE, 1},
8972 {":loader", IMAGE_FUNCTION_VALUE, 0},
8973 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1},
8974 {":ascent", IMAGE_ASCENT_VALUE, 0},
8975 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
8976 {":relief", IMAGE_INTEGER_VALUE, 0},
8977 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8978 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8979 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8980 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
8983 /* Structure describing the image type `ghostscript'. */
8985 static struct image_type gs_type =
8987 &Qpostscript,
8988 gs_image_p,
8989 gs_load,
8990 gs_clear_image,
8991 NULL,
8992 NULL
8996 /* Free X resources of Ghostscript image IMG which is used on frame F. */
8998 static void
8999 gs_clear_image (struct frame *f, struct image *img)
9001 x_clear_image (f, img);
9005 /* Return true if OBJECT is a valid Ghostscript image
9006 specification. */
9008 static bool
9009 gs_image_p (Lisp_Object object)
9011 struct image_keyword fmt[GS_LAST];
9012 Lisp_Object tem;
9013 int i;
9015 memcpy (fmt, gs_format, sizeof fmt);
9017 if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript))
9018 return 0;
9020 /* Bounding box must be a list or vector containing 4 integers. */
9021 tem = fmt[GS_BOUNDING_BOX].value;
9022 if (CONSP (tem))
9024 for (i = 0; i < 4; ++i, tem = XCDR (tem))
9025 if (!CONSP (tem) || !INTEGERP (XCAR (tem)))
9026 return 0;
9027 if (!NILP (tem))
9028 return 0;
9030 else if (VECTORP (tem))
9032 if (ASIZE (tem) != 4)
9033 return 0;
9034 for (i = 0; i < 4; ++i)
9035 if (!INTEGERP (AREF (tem, i)))
9036 return 0;
9038 else
9039 return 0;
9041 return 1;
9045 /* Load Ghostscript image IMG for use on frame F. Value is true
9046 if successful. */
9048 static bool
9049 gs_load (struct frame *f, struct image *img)
9051 uprintmax_t printnum1, printnum2;
9052 char buffer[sizeof " " + INT_STRLEN_BOUND (printmax_t)];
9053 Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width;
9054 Lisp_Object frame;
9055 double in_width, in_height;
9056 Lisp_Object pixel_colors = Qnil;
9058 /* Compute pixel size of pixmap needed from the given size in the
9059 image specification. Sizes in the specification are in pt. 1 pt
9060 = 1/72 in, xdpi and ydpi are stored in the frame's X display
9061 info. */
9062 pt_width = image_spec_value (img->spec, QCpt_width, NULL);
9063 in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0;
9064 in_width *= FRAME_RES_X (f);
9065 pt_height = image_spec_value (img->spec, QCpt_height, NULL);
9066 in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0;
9067 in_height *= FRAME_RES_Y (f);
9069 if (! (in_width <= INT_MAX && in_height <= INT_MAX
9070 && check_image_size (f, in_width, in_height)))
9072 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
9073 return 0;
9075 img->width = in_width;
9076 img->height = in_height;
9078 /* Create the pixmap. */
9079 eassert (img->pixmap == NO_PIXMAP);
9081 if (x_check_image_size (0, img->width, img->height))
9083 /* Only W32 version did BLOCK_INPUT here. ++kfs */
9084 block_input ();
9085 img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
9086 img->width, img->height,
9087 DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
9088 unblock_input ();
9091 if (!img->pixmap)
9093 image_error ("Unable to create pixmap for `%s'", img->spec, Qnil);
9094 return 0;
9097 /* Call the loader to fill the pixmap. It returns a process object
9098 if successful. We do not record_unwind_protect here because
9099 other places in redisplay like calling window scroll functions
9100 don't either. Let the Lisp loader use `unwind-protect' instead. */
9101 printnum1 = FRAME_X_WINDOW (f);
9102 printnum2 = img->pixmap;
9103 window_and_pixmap_id
9104 = make_formatted_string (buffer, "%"pMu" %"pMu, printnum1, printnum2);
9106 printnum1 = FRAME_FOREGROUND_PIXEL (f);
9107 printnum2 = FRAME_BACKGROUND_PIXEL (f);
9108 pixel_colors
9109 = make_formatted_string (buffer, "%"pMu" %"pMu, printnum1, printnum2);
9111 XSETFRAME (frame, f);
9112 loader = image_spec_value (img->spec, QCloader, NULL);
9113 if (NILP (loader))
9114 loader = intern ("gs-load-image");
9116 img->lisp_data = call6 (loader, frame, img->spec,
9117 make_number (img->width),
9118 make_number (img->height),
9119 window_and_pixmap_id,
9120 pixel_colors);
9121 return PROCESSP (img->lisp_data);
9125 /* Kill the Ghostscript process that was started to fill PIXMAP on
9126 frame F. Called from XTread_socket when receiving an event
9127 telling Emacs that Ghostscript has finished drawing. */
9129 void
9130 x_kill_gs_process (Pixmap pixmap, struct frame *f)
9132 struct image_cache *c = FRAME_IMAGE_CACHE (f);
9133 int class;
9134 ptrdiff_t i;
9135 struct image *img;
9137 /* Find the image containing PIXMAP. */
9138 for (i = 0; i < c->used; ++i)
9139 if (c->images[i]->pixmap == pixmap)
9140 break;
9142 /* Should someone in between have cleared the image cache, for
9143 instance, give up. */
9144 if (i == c->used)
9145 return;
9147 /* Kill the GS process. We should have found PIXMAP in the image
9148 cache and its image should contain a process object. */
9149 img = c->images[i];
9150 eassert (PROCESSP (img->lisp_data));
9151 Fkill_process (img->lisp_data, Qnil);
9152 img->lisp_data = Qnil;
9154 #if defined (HAVE_X_WINDOWS)
9156 /* On displays with a mutable colormap, figure out the colors
9157 allocated for the image by looking at the pixels of an XImage for
9158 img->pixmap. */
9159 class = FRAME_X_VISUAL (f)->class;
9160 if (class != StaticColor && class != StaticGray && class != TrueColor)
9162 XImagePtr ximg;
9164 block_input ();
9166 /* Try to get an XImage for img->pixmep. */
9167 ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
9168 0, 0, img->width, img->height, ~0, ZPixmap);
9169 if (ximg)
9171 int x, y;
9173 /* Initialize the color table. */
9174 init_color_table ();
9176 /* For each pixel of the image, look its color up in the
9177 color table. After having done so, the color table will
9178 contain an entry for each color used by the image. */
9179 for (y = 0; y < img->height; ++y)
9180 for (x = 0; x < img->width; ++x)
9182 unsigned long pixel = XGetPixel (ximg, x, y);
9183 lookup_pixel_color (f, pixel);
9186 /* Record colors in the image. Free color table and XImage. */
9187 #ifdef COLOR_TABLE_SUPPORT
9188 img->colors = colors_in_color_table (&img->ncolors);
9189 free_color_table ();
9190 #endif
9191 XDestroyImage (ximg);
9193 #if 0 /* This doesn't seem to be the case. If we free the colors
9194 here, we get a BadAccess later in x_clear_image when
9195 freeing the colors. */
9196 /* We have allocated colors once, but Ghostscript has also
9197 allocated colors on behalf of us. So, to get the
9198 reference counts right, free them once. */
9199 if (img->ncolors)
9200 x_free_colors (f, img->colors, img->ncolors);
9201 #endif
9203 else
9204 image_error ("Cannot get X image of `%s'; colors will not be freed",
9205 img->spec, Qnil);
9207 unblock_input ();
9209 #endif /* HAVE_X_WINDOWS */
9211 /* Now that we have the pixmap, compute mask and transform the
9212 image if requested. */
9213 block_input ();
9214 postprocess_image (f, img);
9215 unblock_input ();
9218 #endif /* HAVE_GHOSTSCRIPT */
9221 /***********************************************************************
9222 Tests
9223 ***********************************************************************/
9225 #ifdef GLYPH_DEBUG
9227 DEFUN ("imagep", Fimagep, Simagep, 1, 1, 0,
9228 doc: /* Value is non-nil if SPEC is a valid image specification. */)
9229 (Lisp_Object spec)
9231 return valid_image_p (spec) ? Qt : Qnil;
9235 DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
9236 (Lisp_Object spec)
9238 ptrdiff_t id = -1;
9240 if (valid_image_p (spec))
9241 id = lookup_image (SELECTED_FRAME (), spec);
9243 debug_print (spec);
9244 return make_number (id);
9247 #endif /* GLYPH_DEBUG */
9250 /***********************************************************************
9251 Initialization
9252 ***********************************************************************/
9254 DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 1, 1, 0,
9255 doc: /* Initialize image library implementing image type TYPE.
9256 Return non-nil if TYPE is a supported image type.
9258 If image libraries are loaded dynamically (currently only the case on
9259 MS-Windows), load the library for TYPE if it is not yet loaded, using
9260 the library file(s) specified by `dynamic-library-alist'. */)
9261 (Lisp_Object type)
9263 return lookup_image_type (type) ? Qt : Qnil;
9266 /* Look up image type TYPE, and return a pointer to its image_type
9267 structure. Return 0 if TYPE is not a known image type. */
9269 static struct image_type *
9270 lookup_image_type (Lisp_Object type)
9272 /* Types pbm and xbm are built-in and always available. */
9273 if (EQ (type, Qpbm))
9274 return define_image_type (&pbm_type);
9276 if (EQ (type, Qxbm))
9277 return define_image_type (&xbm_type);
9279 #if defined (HAVE_XPM) || defined (HAVE_NS)
9280 if (EQ (type, Qxpm))
9281 return define_image_type (&xpm_type);
9282 #endif
9284 #if defined (HAVE_JPEG) || defined (HAVE_NS)
9285 if (EQ (type, Qjpeg))
9286 return define_image_type (&jpeg_type);
9287 #endif
9289 #if defined (HAVE_TIFF) || defined (HAVE_NS)
9290 if (EQ (type, Qtiff))
9291 return define_image_type (&tiff_type);
9292 #endif
9294 #if defined (HAVE_GIF) || defined (HAVE_NS)
9295 if (EQ (type, Qgif))
9296 return define_image_type (&gif_type);
9297 #endif
9299 #if defined (HAVE_PNG) || defined (HAVE_NS)
9300 if (EQ (type, Qpng))
9301 return define_image_type (&png_type);
9302 #endif
9304 #if defined (HAVE_RSVG)
9305 if (EQ (type, Qsvg))
9306 return define_image_type (&svg_type);
9307 #endif
9309 #if defined (HAVE_IMAGEMAGICK)
9310 if (EQ (type, Qimagemagick))
9311 return define_image_type (&imagemagick_type);
9312 #endif
9314 #ifdef HAVE_GHOSTSCRIPT
9315 if (EQ (type, Qpostscript))
9316 return define_image_type (&gs_type);
9317 #endif
9319 return NULL;
9322 /* Reset image_types before dumping.
9323 Called from Fdump_emacs. */
9325 void
9326 reset_image_types (void)
9328 while (image_types)
9330 struct image_type *next = image_types->next;
9331 xfree (image_types);
9332 image_types = next;
9336 void
9337 syms_of_image (void)
9339 /* Initialize this only once; it will be reset before dumping. */
9340 image_types = NULL;
9342 /* Must be defined now because we're going to update it below, while
9343 defining the supported image types. */
9344 DEFVAR_LISP ("image-types", Vimage_types,
9345 doc: /* List of potentially supported image types.
9346 Each element of the list is a symbol for an image type, like 'jpeg or 'png.
9347 To check whether it is really supported, use `image-type-available-p'. */);
9348 Vimage_types = Qnil;
9350 DEFVAR_LISP ("max-image-size", Vmax_image_size,
9351 doc: /* Maximum size of images.
9352 Emacs will not load an image into memory if its pixel width or
9353 pixel height exceeds this limit.
9355 If the value is an integer, it directly specifies the maximum
9356 image height and width, measured in pixels. If it is a floating
9357 point number, it specifies the maximum image height and width
9358 as a ratio to the frame height and width. If the value is
9359 non-numeric, there is no explicit limit on the size of images. */);
9360 Vmax_image_size = make_float (MAX_IMAGE_SIZE);
9362 DEFSYM (Qcount, "count");
9363 DEFSYM (Qextension_data, "extension-data");
9364 DEFSYM (Qdelay, "delay");
9366 DEFSYM (QCascent, ":ascent");
9367 DEFSYM (QCmargin, ":margin");
9368 DEFSYM (QCrelief, ":relief");
9369 DEFSYM (QCconversion, ":conversion");
9370 DEFSYM (QCcolor_symbols, ":color-symbols");
9371 DEFSYM (QCheuristic_mask, ":heuristic-mask");
9372 DEFSYM (QCindex, ":index");
9373 DEFSYM (QCgeometry, ":geometry");
9374 DEFSYM (QCcrop, ":crop");
9375 DEFSYM (QCrotation, ":rotation");
9376 DEFSYM (QCmatrix, ":matrix");
9377 DEFSYM (QCcolor_adjustment, ":color-adjustment");
9378 DEFSYM (QCmask, ":mask");
9380 DEFSYM (Qlaplace, "laplace");
9381 DEFSYM (Qemboss, "emboss");
9382 DEFSYM (Qedge_detection, "edge-detection");
9383 DEFSYM (Qheuristic, "heuristic");
9385 DEFSYM (Qpostscript, "postscript");
9386 DEFSYM (QCmax_width, ":max-width");
9387 DEFSYM (QCmax_height, ":max-height");
9388 #ifdef HAVE_GHOSTSCRIPT
9389 ADD_IMAGE_TYPE (Qpostscript);
9390 DEFSYM (QCloader, ":loader");
9391 DEFSYM (QCbounding_box, ":bounding-box");
9392 DEFSYM (QCpt_width, ":pt-width");
9393 DEFSYM (QCpt_height, ":pt-height");
9394 #endif /* HAVE_GHOSTSCRIPT */
9396 #ifdef HAVE_NTGUI
9397 DEFSYM (Qlibpng_version, "libpng-version");
9398 Fset (Qlibpng_version,
9399 #if HAVE_PNG
9400 make_number (PNG_LIBPNG_VER)
9401 #else
9402 make_number (-1)
9403 #endif
9405 DEFSYM (Qlibgif_version, "libgif-version");
9406 Fset (Qlibgif_version,
9407 #ifdef HAVE_GIF
9408 make_number (GIFLIB_MAJOR * 10000
9409 + GIFLIB_MINOR * 100
9410 + GIFLIB_RELEASE)
9411 #else
9412 make_number (-1)
9413 #endif
9415 #endif
9417 DEFSYM (Qpbm, "pbm");
9418 ADD_IMAGE_TYPE (Qpbm);
9420 DEFSYM (Qxbm, "xbm");
9421 ADD_IMAGE_TYPE (Qxbm);
9423 #if defined (HAVE_XPM) || defined (HAVE_NS)
9424 DEFSYM (Qxpm, "xpm");
9425 ADD_IMAGE_TYPE (Qxpm);
9426 #endif
9428 #if defined (HAVE_JPEG) || defined (HAVE_NS)
9429 DEFSYM (Qjpeg, "jpeg");
9430 ADD_IMAGE_TYPE (Qjpeg);
9431 #endif
9433 #if defined (HAVE_TIFF) || defined (HAVE_NS)
9434 DEFSYM (Qtiff, "tiff");
9435 ADD_IMAGE_TYPE (Qtiff);
9436 #endif
9438 #if defined (HAVE_GIF) || defined (HAVE_NS)
9439 DEFSYM (Qgif, "gif");
9440 ADD_IMAGE_TYPE (Qgif);
9441 #endif
9443 #if defined (HAVE_PNG) || defined (HAVE_NS)
9444 DEFSYM (Qpng, "png");
9445 ADD_IMAGE_TYPE (Qpng);
9446 #endif
9448 #if defined (HAVE_IMAGEMAGICK)
9449 DEFSYM (Qimagemagick, "imagemagick");
9450 ADD_IMAGE_TYPE (Qimagemagick);
9451 #endif
9453 #if defined (HAVE_RSVG)
9454 DEFSYM (Qsvg, "svg");
9455 ADD_IMAGE_TYPE (Qsvg);
9456 #ifdef HAVE_NTGUI
9457 /* Other libraries used directly by svg code. */
9458 DEFSYM (Qgdk_pixbuf, "gdk-pixbuf");
9459 DEFSYM (Qglib, "glib");
9460 DEFSYM (Qgobject, "gobject");
9461 #endif /* HAVE_NTGUI */
9462 #endif /* HAVE_RSVG */
9464 defsubr (&Sinit_image_library);
9465 #ifdef HAVE_IMAGEMAGICK
9466 defsubr (&Simagemagick_types);
9467 #endif
9468 defsubr (&Sclear_image_cache);
9469 defsubr (&Simage_flush);
9470 defsubr (&Simage_size);
9471 defsubr (&Simage_mask_p);
9472 defsubr (&Simage_metadata);
9474 #ifdef GLYPH_DEBUG
9475 defsubr (&Simagep);
9476 defsubr (&Slookup_image);
9477 #endif
9479 DEFVAR_BOOL ("cross-disabled-images", cross_disabled_images,
9480 doc: /* Non-nil means always draw a cross over disabled images.
9481 Disabled images are those having a `:conversion disabled' property.
9482 A cross is always drawn on black & white displays. */);
9483 cross_disabled_images = 0;
9485 DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path,
9486 doc: /* List of directories to search for window system bitmap files. */);
9487 Vx_bitmap_file_path = decode_env_path (0, PATH_BITMAPS);
9489 DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay,
9490 doc: /* Maximum time after which images are removed from the cache.
9491 When an image has not been displayed this many seconds, Emacs
9492 automatically removes it from the image cache. If the cache contains
9493 a large number of images, the actual eviction time may be shorter.
9494 The value can also be nil, meaning the cache is never cleared.
9496 The function `clear-image-cache' disregards this variable. */);
9497 Vimage_cache_eviction_delay = make_number (300);
9498 #ifdef HAVE_IMAGEMAGICK
9499 DEFVAR_INT ("imagemagick-render-type", imagemagick_render_type,
9500 doc: /* Integer indicating which ImageMagick rendering method to use.
9501 The options are:
9502 0 -- the default method (pixel pushing)
9503 1 -- a newer method ("MagickExportImagePixels") that may perform
9504 better (speed etc) in some cases, but has not been as thoroughly
9505 tested with Emacs as the default method. This method requires
9506 ImageMagick version 6.4.6 (approximately) or later.
9507 */);
9508 /* MagickExportImagePixels is in 6.4.6-9, but not 6.4.4-10. */
9509 imagemagick_render_type = 0;
9510 #endif