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