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