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