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