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