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