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