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