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