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