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