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