1 /* Functions for image support on window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
31 #if defined HAVE_LIBPNG_PNG_H
32 # include <libpng/png.h>
40 /* This makes the fields of a Display accessible, in Xlib header files. */
42 #define XLIB_ILLEGAL_ACCESS
47 #include "dispextern.h"
48 #include "blockinput.h"
51 #include "character.h"
53 #include "termhooks.h"
58 #include <sys/types.h>
61 #define COLOR_TABLE_SUPPORT 1
63 typedef struct x_bitmap_record Bitmap_Record
;
64 #define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
65 #define NO_PIXMAP None
67 #define RGB_PIXEL_COLOR unsigned long
69 #define PIX_MASK_RETAIN 0
70 #define PIX_MASK_DRAW 1
71 #endif /* HAVE_X_WINDOWS */
77 /* W32_TODO : Color tables on W32. */
78 #undef COLOR_TABLE_SUPPORT
80 typedef struct w32_bitmap_record Bitmap_Record
;
81 #define GET_PIXEL(ximg, x, y) GetPixel(ximg, x, y)
84 #define RGB_PIXEL_COLOR COLORREF
86 #define PIX_MASK_RETAIN 0
87 #define PIX_MASK_DRAW 1
89 #define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual
90 #define x_defined_color w32_defined_color
91 #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
93 /* Functions from w32term.c that depend on XColor (so can't go in w32term.h
94 without modifying lots of files). */
95 extern void x_query_colors (struct frame
*f
, XColor
*colors
, int ncolors
);
96 extern void x_query_color (struct frame
*f
, XColor
*color
);
97 #endif /* HAVE_NTGUI */
101 #include <sys/types.h>
102 #include <sys/stat.h>
104 #undef COLOR_TABLE_SUPPORT
106 typedef struct ns_bitmap_record Bitmap_Record
;
108 #define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
111 #define RGB_PIXEL_COLOR unsigned long
114 #define PIX_MASK_RETAIN 0
115 #define PIX_MASK_DRAW 1
117 #define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO(f)->visual
118 #define x_defined_color(f, name, color_def, alloc) \
119 ns_defined_color (f, name, color_def, alloc, 0)
120 #define FRAME_X_SCREEN(f) 0
121 #define DefaultDepthOfScreen(screen) x_display_list->n_planes
125 /* Search path for bitmap files. */
127 Lisp_Object Vx_bitmap_file_path
;
130 static void x_disable_image (struct frame
*, struct image
*);
131 static void x_edge_detection (struct frame
*, struct image
*, Lisp_Object
,
134 static void init_color_table (void);
135 static unsigned long lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
);
136 #ifdef COLOR_TABLE_SUPPORT
137 static void free_color_table (void);
138 static unsigned long *colors_in_color_table (int *n
);
139 static unsigned long lookup_pixel_color (struct frame
*f
, unsigned long p
);
142 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
143 id, which is just an int that this section returns. Bitmaps are
144 reference counted so they can be shared among frames.
146 Bitmap indices are guaranteed to be > 0, so a negative number can
147 be used to indicate no bitmap.
149 If you use x_create_bitmap_from_data, then you must keep track of
150 the bitmaps yourself. That is, creating a bitmap from the same
151 data more than once will not be caught. */
155 XGetImage (Display
*display
, Pixmap pixmap
, int x
, int y
,
156 unsigned int width
, unsigned int height
,
157 unsigned long plane_mask
, int format
)
159 /* TODO: not sure what this function is supposed to do.. */
160 ns_retain_object (pixmap
);
164 /* use with imgs created by ns_image_for_XPM */
166 XGetPixel (XImagePtr ximage
, int x
, int y
)
168 return ns_get_pixel (ximage
, x
, y
);
171 /* use with imgs created by ns_image_for_XPM; alpha set to 1;
172 pixel is assumed to be in form RGB */
174 XPutPixel (XImagePtr ximage
, int x
, int y
, unsigned long pixel
)
176 ns_put_pixel (ximage
, x
, y
, pixel
);
181 /* Functions to access the contents of a bitmap, given an id. */
184 x_bitmap_height (FRAME_PTR f
, int id
)
186 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
190 x_bitmap_width (FRAME_PTR f
, int id
)
192 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
195 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
197 x_bitmap_pixmap (FRAME_PTR f
, int id
)
199 return (int) FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
203 #ifdef HAVE_X_WINDOWS
205 x_bitmap_mask (FRAME_PTR f
, int id
)
207 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].mask
;
211 /* Allocate a new bitmap record. Returns index of new record. */
214 x_allocate_bitmap_record (FRAME_PTR f
)
216 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
219 if (dpyinfo
->bitmaps
== NULL
)
221 dpyinfo
->bitmaps_size
= 10;
223 = (Bitmap_Record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (Bitmap_Record
));
224 dpyinfo
->bitmaps_last
= 1;
228 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
229 return ++dpyinfo
->bitmaps_last
;
231 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
232 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
235 dpyinfo
->bitmaps_size
*= 2;
237 = (Bitmap_Record
*) xrealloc (dpyinfo
->bitmaps
,
238 dpyinfo
->bitmaps_size
* sizeof (Bitmap_Record
));
239 return ++dpyinfo
->bitmaps_last
;
242 /* Add one reference to the reference count of the bitmap with id ID. */
245 x_reference_bitmap (FRAME_PTR f
, int id
)
247 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
250 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
253 x_create_bitmap_from_data (struct frame
*f
, char *bits
, unsigned int width
, unsigned int height
)
255 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
258 #ifdef HAVE_X_WINDOWS
260 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
261 bits
, width
, height
);
264 #endif /* HAVE_X_WINDOWS */
268 bitmap
= CreateBitmap (width
, height
,
269 FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_planes
,
270 FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_cbits
,
274 #endif /* HAVE_NTGUI */
277 void *bitmap
= ns_image_from_XBM (bits
, width
, height
);
282 id
= x_allocate_bitmap_record (f
);
285 dpyinfo
->bitmaps
[id
- 1].img
= bitmap
;
286 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
289 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
290 dpyinfo
->bitmaps
[id
- 1].height
= height
;
291 dpyinfo
->bitmaps
[id
- 1].width
= width
;
292 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
294 #ifdef HAVE_X_WINDOWS
295 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
296 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
297 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
298 #endif /* HAVE_X_WINDOWS */
301 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
302 dpyinfo
->bitmaps
[id
- 1].hinst
= NULL
;
303 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
304 #endif /* HAVE_NTGUI */
309 /* Create bitmap from file FILE for frame F. */
312 x_create_bitmap_from_file (struct frame
*f
, Lisp_Object file
)
314 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
317 return -1; /* W32_TODO : bitmap support */
318 #endif /* HAVE_NTGUI */
322 void *bitmap
= ns_image_from_file (file
);
328 id
= x_allocate_bitmap_record (f
);
329 dpyinfo
->bitmaps
[id
- 1].img
= bitmap
;
330 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
331 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (SBYTES (file
) + 1);
332 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
333 dpyinfo
->bitmaps
[id
- 1].height
= ns_image_width (bitmap
);
334 dpyinfo
->bitmaps
[id
- 1].width
= ns_image_height (bitmap
);
335 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
339 #ifdef HAVE_X_WINDOWS
340 unsigned int width
, height
;
342 int xhot
, yhot
, result
, id
;
347 /* Look for an existing bitmap with the same name. */
348 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
350 if (dpyinfo
->bitmaps
[id
].refcount
351 && dpyinfo
->bitmaps
[id
].file
352 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) SDATA (file
)))
354 ++dpyinfo
->bitmaps
[id
].refcount
;
359 /* Search bitmap-file-path for the file, if appropriate. */
360 fd
= openp (Vx_bitmap_file_path
, file
, Qnil
, &found
, Qnil
);
365 filename
= (char *) SDATA (found
);
367 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
368 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
369 if (result
!= BitmapSuccess
)
372 id
= x_allocate_bitmap_record (f
);
373 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
374 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
375 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
376 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (SBYTES (file
) + 1);
377 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
378 dpyinfo
->bitmaps
[id
- 1].height
= height
;
379 dpyinfo
->bitmaps
[id
- 1].width
= width
;
380 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
383 #endif /* HAVE_X_WINDOWS */
389 free_bitmap_record (Display_Info
*dpyinfo
, Bitmap_Record
*bm
)
391 #ifdef HAVE_X_WINDOWS
392 XFreePixmap (dpyinfo
->display
, bm
->pixmap
);
394 XFreePixmap (dpyinfo
->display
, bm
->mask
);
395 #endif /* HAVE_X_WINDOWS */
398 DeleteObject (bm
->pixmap
);
399 #endif /* HAVE_NTGUI */
402 ns_release_object (bm
->img
);
412 /* Remove reference to bitmap with id number ID. */
415 x_destroy_bitmap (FRAME_PTR f
, int id
)
417 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
421 Bitmap_Record
*bm
= &dpyinfo
->bitmaps
[id
- 1];
423 if (--bm
->refcount
== 0)
426 free_bitmap_record (dpyinfo
, bm
);
432 /* Free all the bitmaps for the display specified by DPYINFO. */
435 x_destroy_all_bitmaps (Display_Info
*dpyinfo
)
438 Bitmap_Record
*bm
= dpyinfo
->bitmaps
;
440 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++, bm
++)
441 if (bm
->refcount
> 0)
442 free_bitmap_record (dpyinfo
, bm
);
444 dpyinfo
->bitmaps_last
= 0;
448 #ifdef HAVE_X_WINDOWS
450 /* Useful functions defined in the section
451 `Image type independent image structures' below. */
453 static unsigned long four_corners_best (XImagePtr ximg
,
456 unsigned long height
);
458 static int x_create_x_image_and_pixmap (struct frame
*f
, int width
, int height
,
459 int depth
, XImagePtr
*ximg
,
462 static void x_destroy_x_image (XImagePtr ximg
);
465 /* Create a mask of a bitmap. Note is this not a perfect mask.
466 It's nicer with some borders in this context */
469 x_create_bitmap_mask (struct frame
*f
, int id
)
472 XImagePtr ximg
, mask_img
;
473 unsigned long width
, height
;
476 unsigned long x
, y
, xp
, xm
, yp
, ym
;
479 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
484 pixmap
= x_bitmap_pixmap (f
, id
);
485 width
= x_bitmap_width (f
, id
);
486 height
= x_bitmap_height (f
, id
);
489 ximg
= XGetImage (FRAME_X_DISPLAY (f
), pixmap
, 0, 0, width
, height
,
498 result
= x_create_x_image_and_pixmap (f
, width
, height
, 1, &mask_img
, &mask
);
503 XDestroyImage (ximg
);
507 bg
= four_corners_best (ximg
, NULL
, width
, height
);
509 for (y
= 0; y
< ximg
->height
; ++y
)
511 for (x
= 0; x
< ximg
->width
; ++x
)
513 xp
= x
!= ximg
->width
- 1 ? x
+ 1 : 0;
514 xm
= x
!= 0 ? x
- 1 : ximg
->width
- 1;
515 yp
= y
!= ximg
->height
- 1 ? y
+ 1 : 0;
516 ym
= y
!= 0 ? y
- 1 : ximg
->height
- 1;
517 if (XGetPixel (ximg
, x
, y
) == bg
518 && XGetPixel (ximg
, x
, yp
) == bg
519 && XGetPixel (ximg
, x
, ym
) == bg
520 && XGetPixel (ximg
, xp
, y
) == bg
521 && XGetPixel (ximg
, xp
, yp
) == bg
522 && XGetPixel (ximg
, xp
, ym
) == bg
523 && XGetPixel (ximg
, xm
, y
) == bg
524 && XGetPixel (ximg
, xm
, yp
) == bg
525 && XGetPixel (ximg
, xm
, ym
) == bg
)
526 XPutPixel (mask_img
, x
, y
, 0);
528 XPutPixel (mask_img
, x
, y
, 1);
532 xassert (interrupt_input_blocked
);
533 gc
= XCreateGC (FRAME_X_DISPLAY (f
), mask
, 0, NULL
);
534 XPutImage (FRAME_X_DISPLAY (f
), mask
, gc
, mask_img
, 0, 0, 0, 0,
536 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
538 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
539 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
541 XDestroyImage (ximg
);
542 x_destroy_x_image (mask_img
);
547 #endif /* HAVE_X_WINDOWS */
550 /***********************************************************************
552 ***********************************************************************/
554 /* Value is the number of elements of vector VECTOR. */
556 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
558 /* List of supported image types. Use define_image_type to add new
559 types. Use lookup_image_type to find a type for a given symbol. */
561 static struct image_type
*image_types
;
563 /* A list of symbols, one for each supported image type. */
565 Lisp_Object Vimage_types
;
567 /* An alist of image types and libraries that implement the type. */
569 Lisp_Object Vimage_library_alist
;
571 /* Cache for delayed-loading image types. */
573 static Lisp_Object Vimage_type_cache
;
575 /* The symbol `xbm' which is used as the type symbol for XBM images. */
581 extern Lisp_Object QCwidth
, QCheight
, QCforeground
, QCbackground
, QCfile
;
582 extern Lisp_Object QCdata
, QCtype
;
583 extern Lisp_Object Qcenter
;
584 Lisp_Object QCascent
, QCmargin
, QCrelief
, Qcount
, Qextension_data
;
585 Lisp_Object QCconversion
, QCcolor_symbols
, QCheuristic_mask
;
586 Lisp_Object QCindex
, QCmatrix
, QCcolor_adjustment
, QCmask
;
590 Lisp_Object Qlaplace
, Qemboss
, Qedge_detection
, Qheuristic
;
592 /* Time in seconds after which images should be removed from the cache
595 Lisp_Object Vimage_cache_eviction_delay
;
597 /* Function prototypes. */
599 static Lisp_Object
define_image_type (struct image_type
*type
, int loaded
);
600 static struct image_type
*lookup_image_type (Lisp_Object symbol
);
601 static void image_error (char *format
, Lisp_Object
, Lisp_Object
);
602 static void x_laplace (struct frame
*, struct image
*);
603 static void x_emboss (struct frame
*, struct image
*);
604 static int x_build_heuristic_mask (struct frame
*, struct image
*,
607 #define CACHE_IMAGE_TYPE(type, status) \
608 do { Vimage_type_cache = Fcons (Fcons (type, status), Vimage_type_cache); } while (0)
610 #define ADD_IMAGE_TYPE(type) \
611 do { Vimage_types = Fcons (type, Vimage_types); } while (0)
613 /* Define a new image type from TYPE. This adds a copy of TYPE to
614 image_types and caches the loading status of TYPE. */
617 define_image_type (struct image_type
*type
, int loaded
)
625 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
626 The initialized data segment is read-only. */
627 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
628 memcpy (p
, type
, sizeof *p
);
629 p
->next
= image_types
;
634 CACHE_IMAGE_TYPE (*type
->type
, success
);
639 /* Look up image type SYMBOL, and return a pointer to its image_type
640 structure. Value is null if SYMBOL is not a known image type. */
642 static INLINE
struct image_type
*
643 lookup_image_type (Lisp_Object symbol
)
645 struct image_type
*type
;
647 /* We must initialize the image-type if it hasn't been already. */
648 if (NILP (Finit_image_library (symbol
, Vimage_library_alist
)))
649 return 0; /* unimplemented */
651 for (type
= image_types
; type
; type
= type
->next
)
652 if (EQ (symbol
, *type
->type
))
659 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
660 valid image specification is a list whose car is the symbol
661 `image', and whose rest is a property list. The property list must
662 contain a value for key `:type'. That value must be the name of a
663 supported image type. The rest of the property list depends on the
667 valid_image_p (Lisp_Object object
)
675 for (tem
= XCDR (object
); CONSP (tem
); tem
= XCDR (tem
))
676 if (EQ (XCAR (tem
), QCtype
))
679 if (CONSP (tem
) && SYMBOLP (XCAR (tem
)))
681 struct image_type
*type
;
682 type
= lookup_image_type (XCAR (tem
));
684 valid_p
= type
->valid_p (object
);
695 /* Log error message with format string FORMAT and argument ARG.
696 Signaling an error, e.g. when an image cannot be loaded, is not a
697 good idea because this would interrupt redisplay, and the error
698 message display would lead to another redisplay. This function
699 therefore simply displays a message. */
702 image_error (char *format
, Lisp_Object arg1
, Lisp_Object arg2
)
704 add_to_log (format
, arg1
, arg2
);
709 /***********************************************************************
711 ***********************************************************************/
713 enum image_value_type
715 IMAGE_DONT_CHECK_VALUE_TYPE
,
717 IMAGE_STRING_OR_NIL_VALUE
,
719 IMAGE_POSITIVE_INTEGER_VALUE
,
720 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
721 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
724 IMAGE_FUNCTION_VALUE
,
729 /* Structure used when parsing image specifications. */
733 /* Name of keyword. */
736 /* The type of value allowed. */
737 enum image_value_type type
;
739 /* Non-zero means key must be present. */
742 /* Used to recognize duplicate keywords in a property list. */
745 /* The value that was found. */
750 static int parse_image_spec (Lisp_Object
, struct image_keyword
*,
752 static Lisp_Object
image_spec_value (Lisp_Object
, Lisp_Object
, int *);
755 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
756 has the format (image KEYWORD VALUE ...). One of the keyword/
757 value pairs must be `:type TYPE'. KEYWORDS is a vector of
758 image_keywords structures of size NKEYWORDS describing other
759 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
762 parse_image_spec (Lisp_Object spec
, struct image_keyword
*keywords
,
763 int nkeywords
, Lisp_Object type
)
772 while (CONSP (plist
))
774 Lisp_Object key
, value
;
776 /* First element of a pair must be a symbol. */
778 plist
= XCDR (plist
);
782 /* There must follow a value. */
785 value
= XCAR (plist
);
786 plist
= XCDR (plist
);
788 /* Find key in KEYWORDS. Error if not found. */
789 for (i
= 0; i
< nkeywords
; ++i
)
790 if (strcmp (keywords
[i
].name
, SDATA (SYMBOL_NAME (key
))) == 0)
796 /* Record that we recognized the keyword. If a keywords
797 was found more than once, it's an error. */
798 keywords
[i
].value
= value
;
801 if (keywords
[i
].count
> 1)
804 /* Check type of value against allowed type. */
805 switch (keywords
[i
].type
)
807 case IMAGE_STRING_VALUE
:
808 if (!STRINGP (value
))
812 case IMAGE_STRING_OR_NIL_VALUE
:
813 if (!STRINGP (value
) && !NILP (value
))
817 case IMAGE_SYMBOL_VALUE
:
818 if (!SYMBOLP (value
))
822 case IMAGE_POSITIVE_INTEGER_VALUE
:
823 if (!INTEGERP (value
) || XINT (value
) <= 0)
827 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
828 if (INTEGERP (value
) && XINT (value
) >= 0)
831 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
832 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
836 case IMAGE_ASCENT_VALUE
:
837 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
839 else if (INTEGERP (value
)
841 && XINT (value
) <= 100)
845 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
846 if (!INTEGERP (value
) || XINT (value
) < 0)
850 case IMAGE_DONT_CHECK_VALUE_TYPE
:
853 case IMAGE_FUNCTION_VALUE
:
854 value
= indirect_function (value
);
857 || (CONSP (value
) && EQ (XCAR (value
), Qlambda
)))
861 case IMAGE_NUMBER_VALUE
:
862 if (!INTEGERP (value
) && !FLOATP (value
))
866 case IMAGE_INTEGER_VALUE
:
867 if (!INTEGERP (value
))
871 case IMAGE_BOOL_VALUE
:
872 if (!NILP (value
) && !EQ (value
, Qt
))
881 if (EQ (key
, QCtype
) && !EQ (type
, value
))
885 /* Check that all mandatory fields are present. */
886 for (i
= 0; i
< nkeywords
; ++i
)
887 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
894 /* Return the value of KEY in image specification SPEC. Value is nil
895 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
896 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
899 image_spec_value (Lisp_Object spec
, Lisp_Object key
, int *found
)
903 xassert (valid_image_p (spec
));
905 for (tail
= XCDR (spec
);
906 CONSP (tail
) && CONSP (XCDR (tail
));
907 tail
= XCDR (XCDR (tail
)))
909 if (EQ (XCAR (tail
), key
))
913 return XCAR (XCDR (tail
));
923 DEFUN ("image-size", Fimage_size
, Simage_size
, 1, 3, 0,
924 doc
: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
925 PIXELS non-nil means return the size in pixels, otherwise return the
926 size in canonical character units.
927 FRAME is the frame on which the image will be displayed. FRAME nil
928 or omitted means use the selected frame. */)
929 (Lisp_Object spec
, Lisp_Object pixels
, Lisp_Object frame
)
934 if (valid_image_p (spec
))
936 struct frame
*f
= check_x_frame (frame
);
937 int id
= lookup_image (f
, spec
);
938 struct image
*img
= IMAGE_FROM_ID (f
, id
);
939 int width
= img
->width
+ 2 * img
->hmargin
;
940 int height
= img
->height
+ 2 * img
->vmargin
;
943 size
= Fcons (make_float ((double) width
/ FRAME_COLUMN_WIDTH (f
)),
944 make_float ((double) height
/ FRAME_LINE_HEIGHT (f
)));
946 size
= Fcons (make_number (width
), make_number (height
));
949 error ("Invalid image specification");
955 DEFUN ("image-mask-p", Fimage_mask_p
, Simage_mask_p
, 1, 2, 0,
956 doc
: /* Return t if image SPEC has a mask bitmap.
957 FRAME is the frame on which the image will be displayed. FRAME nil
958 or omitted means use the selected frame. */)
959 (Lisp_Object spec
, Lisp_Object frame
)
964 if (valid_image_p (spec
))
966 struct frame
*f
= check_x_frame (frame
);
967 int id
= lookup_image (f
, spec
);
968 struct image
*img
= IMAGE_FROM_ID (f
, id
);
973 error ("Invalid image specification");
978 DEFUN ("image-metadata", Fimage_metadata
, Simage_metadata
, 1, 2, 0,
979 doc
: /* Return metadata for image SPEC.
980 FRAME is the frame on which the image will be displayed. FRAME nil
981 or omitted means use the selected frame. */)
982 (Lisp_Object spec
, Lisp_Object frame
)
987 if (valid_image_p (spec
))
989 struct frame
*f
= check_x_frame (frame
);
990 int id
= lookup_image (f
, spec
);
991 struct image
*img
= IMAGE_FROM_ID (f
, id
);
992 ext
= img
->data
.lisp_val
;
999 /***********************************************************************
1000 Image type independent image structures
1001 ***********************************************************************/
1003 static struct image
*make_image (Lisp_Object spec
, unsigned hash
);
1004 static void free_image (struct frame
*f
, struct image
*img
);
1005 static int check_image_size (struct frame
*f
, int width
, int height
);
1007 #define MAX_IMAGE_SIZE 6.0
1008 Lisp_Object Vmax_image_size
;
1010 /* Allocate and return a new image structure for image specification
1011 SPEC. SPEC has a hash value of HASH. */
1013 static struct image
*
1014 make_image (Lisp_Object spec
, unsigned int hash
)
1016 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
1017 Lisp_Object file
= image_spec_value (spec
, QCfile
, NULL
);
1019 xassert (valid_image_p (spec
));
1020 memset (img
, 0, sizeof *img
);
1021 img
->dependencies
= NILP (file
) ? Qnil
: list1 (file
);
1022 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
1023 xassert (img
->type
!= NULL
);
1025 img
->data
.lisp_val
= Qnil
;
1026 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
1028 img
->corners
[BOT_CORNER
] = -1; /* Full image */
1033 /* Free image IMG which was used on frame F, including its resources. */
1036 free_image (struct frame
*f
, struct image
*img
)
1040 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1042 /* Remove IMG from the hash table of its cache. */
1044 img
->prev
->next
= img
->next
;
1046 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
1049 img
->next
->prev
= img
->prev
;
1051 c
->images
[img
->id
] = NULL
;
1053 /* Free resources, then free IMG. */
1054 img
->type
->free (f
, img
);
1059 /* Return 1 if the given widths and heights are valid for display;
1060 otherwise, return 0. */
1063 check_image_size (struct frame
*f
, int width
, int height
)
1067 if (width
<= 0 || height
<= 0)
1070 if (INTEGERP (Vmax_image_size
))
1071 w
= h
= XINT (Vmax_image_size
);
1072 else if (FLOATP (Vmax_image_size
))
1076 w
= FRAME_PIXEL_WIDTH (f
);
1077 h
= FRAME_PIXEL_HEIGHT (f
);
1080 w
= h
= 1024; /* Arbitrary size for unknown frame. */
1081 w
= (int) (XFLOAT_DATA (Vmax_image_size
) * w
);
1082 h
= (int) (XFLOAT_DATA (Vmax_image_size
) * h
);
1087 return (width
<= w
&& height
<= h
);
1090 /* Prepare image IMG for display on frame F. Must be called before
1091 drawing an image. */
1094 prepare_image_for_display (struct frame
*f
, struct image
*img
)
1098 /* We're about to display IMG, so set its timestamp to `now'. */
1100 img
->timestamp
= EMACS_SECS (t
);
1102 /* If IMG doesn't have a pixmap yet, load it now, using the image
1103 type dependent loader function. */
1104 if (img
->pixmap
== NO_PIXMAP
&& !img
->load_failed_p
)
1105 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
1110 /* Value is the number of pixels for the ascent of image IMG when
1111 drawn in face FACE. */
1114 image_ascent (struct image
*img
, struct face
*face
, struct glyph_slice
*slice
)
1119 if (slice
->height
== img
->height
)
1120 height
= img
->height
+ img
->vmargin
;
1121 else if (slice
->y
== 0)
1122 height
= slice
->height
+ img
->vmargin
;
1124 height
= slice
->height
;
1126 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
1131 /* W32 specific version. Why?. ++kfs */
1132 ascent
= height
/ 2 - (FONT_DESCENT (face
->font
)
1133 - FONT_BASE (face
->font
)) / 2;
1135 /* This expression is arranged so that if the image can't be
1136 exactly centered, it will be moved slightly up. This is
1137 because a typical font is `top-heavy' (due to the presence
1138 uppercase letters), so the image placement should err towards
1139 being top-heavy too. It also just generally looks better. */
1140 ascent
= (height
+ FONT_BASE(face
->font
)
1141 - FONT_DESCENT(face
->font
) + 1) / 2;
1142 #endif /* HAVE_NTGUI */
1145 ascent
= height
/ 2;
1148 ascent
= (int) (height
* img
->ascent
/ 100.0);
1154 /* Image background colors. */
1156 /* Find the "best" corner color of a bitmap.
1157 On W32, XIMG is assumed to a device context with the bitmap selected. */
1159 static RGB_PIXEL_COLOR
1160 four_corners_best (XImagePtr_or_DC ximg
, int *corners
,
1161 unsigned long width
, unsigned long height
)
1163 RGB_PIXEL_COLOR corner_pixels
[4], best
;
1166 if (corners
&& corners
[BOT_CORNER
] >= 0)
1168 /* Get the colors at the corner_pixels of ximg. */
1169 corner_pixels
[0] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[TOP_CORNER
]);
1170 corner_pixels
[1] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[TOP_CORNER
]);
1171 corner_pixels
[2] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[BOT_CORNER
] - 1);
1172 corner_pixels
[3] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[BOT_CORNER
] - 1);
1176 /* Get the colors at the corner_pixels of ximg. */
1177 corner_pixels
[0] = GET_PIXEL (ximg
, 0, 0);
1178 corner_pixels
[1] = GET_PIXEL (ximg
, width
- 1, 0);
1179 corner_pixels
[2] = GET_PIXEL (ximg
, width
- 1, height
- 1);
1180 corner_pixels
[3] = GET_PIXEL (ximg
, 0, height
- 1);
1182 /* Choose the most frequently found color as background. */
1183 for (i
= best_count
= 0; i
< 4; ++i
)
1187 for (j
= n
= 0; j
< 4; ++j
)
1188 if (corner_pixels
[i
] == corner_pixels
[j
])
1192 best
= corner_pixels
[i
], best_count
= n
;
1198 /* Portability macros */
1202 #define Destroy_Image(img_dc, prev) \
1203 do { SelectObject (img_dc, prev); DeleteDC (img_dc); } while (0)
1205 #define Free_Pixmap(display, pixmap) \
1206 DeleteObject (pixmap)
1208 #elif defined (HAVE_NS)
1210 #define Destroy_Image(ximg, dummy) \
1211 ns_release_object (ximg)
1213 #define Free_Pixmap(display, pixmap) \
1214 ns_release_object (pixmap)
1218 #define Destroy_Image(ximg, dummy) \
1219 XDestroyImage (ximg)
1221 #define Free_Pixmap(display, pixmap) \
1222 XFreePixmap (display, pixmap)
1224 #endif /* !HAVE_NTGUI && !HAVE_NS */
1227 /* Return the `background' field of IMG. If IMG doesn't have one yet,
1228 it is guessed heuristically. If non-zero, XIMG is an existing
1229 XImage object (or device context with the image selected on W32) to
1230 use for the heuristic. */
1233 image_background (struct image
*img
, struct frame
*f
, XImagePtr_or_DC ximg
)
1235 if (! img
->background_valid
)
1236 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1238 int free_ximg
= !ximg
;
1241 #endif /* HAVE_NTGUI */
1246 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
1247 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
1249 HDC frame_dc
= get_frame_dc (f
);
1250 ximg
= CreateCompatibleDC (frame_dc
);
1251 release_frame_dc (f
, frame_dc
);
1252 prev
= SelectObject (ximg
, img
->pixmap
);
1253 #endif /* !HAVE_NTGUI */
1256 img
->background
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
1259 Destroy_Image (ximg
, prev
);
1261 img
->background_valid
= 1;
1264 return img
->background
;
1267 /* Return the `background_transparent' field of IMG. If IMG doesn't
1268 have one yet, it is guessed heuristically. If non-zero, MASK is an
1269 existing XImage object to use for the heuristic. */
1272 image_background_transparent (struct image
*img
, struct frame
*f
, XImagePtr_or_DC mask
)
1274 if (! img
->background_transparent_valid
)
1275 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1279 int free_mask
= !mask
;
1282 #endif /* HAVE_NTGUI */
1287 mask
= XGetImage (FRAME_X_DISPLAY (f
), img
->mask
,
1288 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
1290 HDC frame_dc
= get_frame_dc (f
);
1291 mask
= CreateCompatibleDC (frame_dc
);
1292 release_frame_dc (f
, frame_dc
);
1293 prev
= SelectObject (mask
, img
->mask
);
1294 #endif /* HAVE_NTGUI */
1297 img
->background_transparent
1298 = (four_corners_best (mask
, img
->corners
, img
->width
, img
->height
) == PIX_MASK_RETAIN
);
1301 Destroy_Image (mask
, prev
);
1304 img
->background_transparent
= 0;
1306 img
->background_transparent_valid
= 1;
1309 return img
->background_transparent
;
1313 /***********************************************************************
1314 Helper functions for X image types
1315 ***********************************************************************/
1317 static void x_clear_image_1 (struct frame
*, struct image
*, int,
1319 static void x_clear_image (struct frame
*f
, struct image
*img
);
1320 static unsigned long x_alloc_image_color (struct frame
*f
,
1322 Lisp_Object color_name
,
1323 unsigned long dflt
);
1326 /* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
1327 free the pixmap if any. MASK_P non-zero means clear the mask
1328 pixmap if any. COLORS_P non-zero means free colors allocated for
1329 the image, if any. */
1332 x_clear_image_1 (struct frame
*f
, struct image
*img
, int pixmap_p
, int mask_p
,
1335 if (pixmap_p
&& img
->pixmap
)
1337 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
1338 img
->pixmap
= NO_PIXMAP
;
1339 /* NOTE (HAVE_NS): background color is NOT an indexed color! */
1340 img
->background_valid
= 0;
1343 if (mask_p
&& img
->mask
)
1345 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
1346 img
->mask
= NO_PIXMAP
;
1347 img
->background_transparent_valid
= 0;
1350 if (colors_p
&& img
->ncolors
)
1352 /* W32_TODO: color table support. */
1353 #ifdef HAVE_X_WINDOWS
1354 x_free_colors (f
, img
->colors
, img
->ncolors
);
1355 #endif /* HAVE_X_WINDOWS */
1356 xfree (img
->colors
);
1363 /* Free X resources of image IMG which is used on frame F. */
1366 x_clear_image (struct frame
*f
, struct image
*img
)
1369 x_clear_image_1 (f
, img
, 1, 1, 1);
1374 /* Allocate color COLOR_NAME for image IMG on frame F. If color
1375 cannot be allocated, use DFLT. Add a newly allocated color to
1376 IMG->colors, so that it can be freed again. Value is the pixel
1379 static unsigned long
1380 x_alloc_image_color (struct frame
*f
, struct image
*img
, Lisp_Object color_name
,
1384 unsigned long result
;
1386 xassert (STRINGP (color_name
));
1388 if (x_defined_color (f
, SDATA (color_name
), &color
, 1))
1390 /* This isn't called frequently so we get away with simply
1391 reallocating the color vector to the needed size, here. */
1394 (unsigned long *) xrealloc (img
->colors
,
1395 img
->ncolors
* sizeof *img
->colors
);
1396 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
1397 result
= color
.pixel
;
1407 /***********************************************************************
1409 ***********************************************************************/
1411 static struct image
*search_image_cache (struct frame
*, Lisp_Object
, unsigned);
1412 static void cache_image (struct frame
*f
, struct image
*img
);
1413 static void postprocess_image (struct frame
*, struct image
*);
1415 /* Return a new, initialized image cache that is allocated from the
1416 heap. Call free_image_cache to free an image cache. */
1418 struct image_cache
*
1419 make_image_cache (void)
1421 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
1424 memset (c
, 0, sizeof *c
);
1426 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
1427 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
1428 c
->buckets
= (struct image
**) xmalloc (size
);
1429 memset (c
->buckets
, 0, size
);
1434 /* Find an image matching SPEC in the cache, and return it. If no
1435 image is found, return NULL. */
1436 static struct image
*
1437 search_image_cache (struct frame
*f
, Lisp_Object spec
, unsigned int hash
)
1440 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1441 int i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1443 if (!c
) return NULL
;
1445 /* If the image spec does not specify a background color, the cached
1446 image must have the same background color as the current frame.
1447 The foreground color must also match, for the sake of monochrome
1450 In fact, we could ignore the foreground color matching condition
1451 for color images, or if the image spec specifies :foreground;
1452 similarly we could ignore the background color matching condition
1453 for formats that don't use transparency (such as jpeg), or if the
1454 image spec specifies :background. However, the extra memory
1455 usage is probably negligible in practice, so we don't bother. */
1457 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
1458 if (img
->hash
== hash
1459 && !NILP (Fequal (img
->spec
, spec
))
1460 && img
->frame_foreground
== FRAME_FOREGROUND_PIXEL (f
)
1461 && img
->frame_background
== FRAME_BACKGROUND_PIXEL (f
))
1467 /* Search frame F for an image with spec SPEC, and free it. */
1470 uncache_image (struct frame
*f
, Lisp_Object spec
)
1472 struct image
*img
= search_image_cache (f
, spec
, sxhash (spec
, 0));
1474 free_image (f
, img
);
1478 /* Free image cache of frame F. Be aware that X frames share images
1482 free_image_cache (struct frame
*f
)
1484 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1489 /* Cache should not be referenced by any frame when freed. */
1490 xassert (c
->refcount
== 0);
1492 for (i
= 0; i
< c
->used
; ++i
)
1493 free_image (f
, c
->images
[i
]);
1497 FRAME_IMAGE_CACHE (f
) = NULL
;
1502 /* Clear image cache of frame F. FILTER=t means free all images.
1503 FILTER=nil means clear only images that haven't been
1504 displayed for some time.
1505 Else, only free the images which have FILTER in their `dependencies'.
1506 Should be called from time to time to reduce the number of loaded images.
1507 If image-cache-eviction-delay is non-nil, this frees images in the cache
1508 which weren't displayed for at least that many seconds. */
1511 clear_image_cache (struct frame
*f
, Lisp_Object filter
)
1513 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1519 /* Block input so that we won't be interrupted by a SIGIO
1520 while being in an inconsistent state. */
1525 /* Filter image cache. */
1526 for (i
= 0; i
< c
->used
; ++i
)
1528 struct image
*img
= c
->images
[i
];
1529 if (img
&& (EQ (Qt
, filter
)
1530 || !NILP (Fmember (filter
, img
->dependencies
))))
1532 free_image (f
, img
);
1537 else if (INTEGERP (Vimage_cache_eviction_delay
))
1539 /* Free cache based on timestamp. */
1542 int delay
, nimages
= 0;
1544 for (i
= 0; i
< c
->used
; ++i
)
1548 /* If the number of cached images has grown unusually large,
1549 decrease the cache eviction delay (Bug#6230). */
1550 delay
= XFASTINT (Vimage_cache_eviction_delay
);
1552 delay
= max (1, 1600 * delay
/ (nimages
*nimages
));
1555 old
= EMACS_SECS (t
) - delay
;
1557 for (i
= 0; i
< c
->used
; ++i
)
1559 struct image
*img
= c
->images
[i
];
1560 if (img
&& img
->timestamp
< old
)
1562 free_image (f
, img
);
1568 /* We may be clearing the image cache because, for example,
1569 Emacs was iconified for a longer period of time. In that
1570 case, current matrices may still contain references to
1571 images freed above. So, clear these matrices. */
1574 Lisp_Object tail
, frame
;
1576 FOR_EACH_FRAME (tail
, frame
)
1578 struct frame
*f
= XFRAME (frame
);
1579 if (FRAME_IMAGE_CACHE (f
) == c
)
1580 clear_current_matrices (f
);
1583 ++windows_or_buffers_changed
;
1591 clear_image_caches (Lisp_Object filter
)
1593 /* FIXME: We want to do
1594 * struct terminal *t;
1595 * for (t = terminal_list; t; t = t->next_terminal)
1596 * clear_image_cache (t, filter); */
1597 Lisp_Object tail
, frame
;
1598 FOR_EACH_FRAME (tail
, frame
)
1599 if (FRAME_WINDOW_P (XFRAME (frame
)))
1600 clear_image_cache (XFRAME (frame
), filter
);
1603 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
1605 doc
: /* Clear the image cache.
1606 FILTER nil or a frame means clear all images in the selected frame.
1607 FILTER t means clear the image caches of all frames.
1608 Anything else, means only clear those images which refer to FILTER,
1609 which is then usually a filename. */)
1610 (Lisp_Object filter
)
1612 if (!(EQ (filter
, Qnil
) || FRAMEP (filter
)))
1613 clear_image_caches (filter
);
1615 clear_image_cache (check_x_frame (filter
), Qt
);
1621 DEFUN ("image-flush", Fimage_flush
, Simage_flush
,
1623 doc
: /* Fush the image with specification SPEC on frame FRAME.
1624 This removes the image from the Emacs image cache. If SPEC specifies
1625 an image file, the next redisplay of this image will read from the
1626 current contents of that file.
1628 FRAME nil or omitted means use the selected frame.
1629 FRAME t means refresh the image on all frames. */)
1630 (Lisp_Object spec
, Lisp_Object frame
)
1632 if (!valid_image_p (spec
))
1633 error ("Invalid image specification");
1638 FOR_EACH_FRAME (tail
, frame
)
1640 struct frame
*f
= XFRAME (frame
);
1641 if (FRAME_WINDOW_P (f
))
1642 uncache_image (f
, spec
);
1646 uncache_image (check_x_frame (frame
), spec
);
1652 /* Compute masks and transform image IMG on frame F, as specified
1653 by the image's specification, */
1656 postprocess_image (struct frame
*f
, struct image
*img
)
1658 /* Manipulation of the image's mask. */
1661 Lisp_Object conversion
, spec
;
1666 /* `:heuristic-mask t'
1668 means build a mask heuristically.
1669 `:heuristic-mask (R G B)'
1670 `:mask (heuristic (R G B))'
1671 means build a mask from color (R G B) in the
1674 means remove a mask, if any. */
1676 mask
= image_spec_value (spec
, QCheuristic_mask
, NULL
);
1678 x_build_heuristic_mask (f
, img
, mask
);
1683 mask
= image_spec_value (spec
, QCmask
, &found_p
);
1685 if (EQ (mask
, Qheuristic
))
1686 x_build_heuristic_mask (f
, img
, Qt
);
1687 else if (CONSP (mask
)
1688 && EQ (XCAR (mask
), Qheuristic
))
1690 if (CONSP (XCDR (mask
)))
1691 x_build_heuristic_mask (f
, img
, XCAR (XCDR (mask
)));
1693 x_build_heuristic_mask (f
, img
, XCDR (mask
));
1695 else if (NILP (mask
) && found_p
&& img
->mask
)
1697 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
1698 img
->mask
= NO_PIXMAP
;
1703 /* Should we apply an image transformation algorithm? */
1704 conversion
= image_spec_value (spec
, QCconversion
, NULL
);
1705 if (EQ (conversion
, Qdisabled
))
1706 x_disable_image (f
, img
);
1707 else if (EQ (conversion
, Qlaplace
))
1709 else if (EQ (conversion
, Qemboss
))
1711 else if (CONSP (conversion
)
1712 && EQ (XCAR (conversion
), Qedge_detection
))
1715 tem
= XCDR (conversion
);
1717 x_edge_detection (f
, img
,
1718 Fplist_get (tem
, QCmatrix
),
1719 Fplist_get (tem
, QCcolor_adjustment
));
1725 /* Return the id of image with Lisp specification SPEC on frame F.
1726 SPEC must be a valid Lisp image specification (see valid_image_p). */
1729 lookup_image (struct frame
*f
, Lisp_Object spec
)
1731 struct image_cache
*c
;
1734 struct gcpro gcpro1
;
1737 /* F must be a window-system frame, and SPEC must be a valid image
1739 xassert (FRAME_WINDOW_P (f
));
1740 xassert (valid_image_p (spec
));
1742 c
= FRAME_IMAGE_CACHE (f
);
1746 /* Look up SPEC in the hash table of the image cache. */
1747 hash
= sxhash (spec
, 0);
1748 img
= search_image_cache (f
, spec
, hash
);
1749 if (img
&& img
->load_failed_p
)
1751 free_image (f
, img
);
1755 /* If not found, create a new image and cache it. */
1758 extern Lisp_Object Qpostscript
;
1761 img
= make_image (spec
, hash
);
1762 cache_image (f
, img
);
1763 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
1764 img
->frame_foreground
= FRAME_FOREGROUND_PIXEL (f
);
1765 img
->frame_background
= FRAME_BACKGROUND_PIXEL (f
);
1767 /* If we can't load the image, and we don't have a width and
1768 height, use some arbitrary width and height so that we can
1769 draw a rectangle for it. */
1770 if (img
->load_failed_p
)
1774 value
= image_spec_value (spec
, QCwidth
, NULL
);
1775 img
->width
= (INTEGERP (value
)
1776 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
1777 value
= image_spec_value (spec
, QCheight
, NULL
);
1778 img
->height
= (INTEGERP (value
)
1779 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
1783 /* Handle image type independent image attributes
1784 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
1785 `:background COLOR'. */
1786 Lisp_Object ascent
, margin
, relief
, bg
;
1788 ascent
= image_spec_value (spec
, QCascent
, NULL
);
1789 if (INTEGERP (ascent
))
1790 img
->ascent
= XFASTINT (ascent
);
1791 else if (EQ (ascent
, Qcenter
))
1792 img
->ascent
= CENTERED_IMAGE_ASCENT
;
1794 margin
= image_spec_value (spec
, QCmargin
, NULL
);
1795 if (INTEGERP (margin
) && XINT (margin
) >= 0)
1796 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
1797 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
1798 && INTEGERP (XCDR (margin
)))
1800 if (XINT (XCAR (margin
)) > 0)
1801 img
->hmargin
= XFASTINT (XCAR (margin
));
1802 if (XINT (XCDR (margin
)) > 0)
1803 img
->vmargin
= XFASTINT (XCDR (margin
));
1806 relief
= image_spec_value (spec
, QCrelief
, NULL
);
1807 if (INTEGERP (relief
))
1809 img
->relief
= XINT (relief
);
1810 img
->hmargin
+= eabs (img
->relief
);
1811 img
->vmargin
+= eabs (img
->relief
);
1814 if (! img
->background_valid
)
1816 bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
1820 = x_alloc_image_color (f
, img
, bg
,
1821 FRAME_BACKGROUND_PIXEL (f
));
1822 img
->background_valid
= 1;
1826 /* Do image transformations and compute masks, unless we
1827 don't have the image yet. */
1828 if (!EQ (*img
->type
->type
, Qpostscript
))
1829 postprocess_image (f
, img
);
1835 /* We're using IMG, so set its timestamp to `now'. */
1836 EMACS_GET_TIME (now
);
1837 img
->timestamp
= EMACS_SECS (now
);
1841 /* Value is the image id. */
1846 /* Cache image IMG in the image cache of frame F. */
1849 cache_image (struct frame
*f
, struct image
*img
)
1851 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1854 /* Find a free slot in c->images. */
1855 for (i
= 0; i
< c
->used
; ++i
)
1856 if (c
->images
[i
] == NULL
)
1859 /* If no free slot found, maybe enlarge c->images. */
1860 if (i
== c
->used
&& c
->used
== c
->size
)
1863 c
->images
= (struct image
**) xrealloc (c
->images
,
1864 c
->size
* sizeof *c
->images
);
1867 /* Add IMG to c->images, and assign IMG an id. */
1873 /* Add IMG to the cache's hash table. */
1874 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1875 img
->next
= c
->buckets
[i
];
1877 img
->next
->prev
= img
;
1879 c
->buckets
[i
] = img
;
1883 /* Call FN on every image in the image cache of frame F. Used to mark
1884 Lisp Objects in the image cache. */
1886 /* Mark Lisp objects in image IMG. */
1889 mark_image (struct image
*img
)
1891 mark_object (img
->spec
);
1892 mark_object (img
->dependencies
);
1894 if (!NILP (img
->data
.lisp_val
))
1895 mark_object (img
->data
.lisp_val
);
1900 mark_image_cache (struct image_cache
*c
)
1905 for (i
= 0; i
< c
->used
; ++i
)
1907 mark_image (c
->images
[i
]);
1913 /***********************************************************************
1914 X / NS / W32 support code
1915 ***********************************************************************/
1919 /* Macro for defining functions that will be loaded from image DLLs. */
1920 #define DEF_IMGLIB_FN(func) int (FAR CDECL *fn_##func)()
1922 /* Macro for loading those image functions from the library. */
1923 #define LOAD_IMGLIB_FN(lib,func) { \
1924 fn_##func = (void *) GetProcAddress (lib, #func); \
1925 if (!fn_##func) return 0; \
1928 /* Load a DLL implementing an image type.
1929 The `image-library-alist' variable associates a symbol,
1930 identifying an image type, to a list of possible filenames.
1931 The function returns NULL if no library could be loaded for
1932 the given image type, or if the library was previously loaded;
1933 else the handle of the DLL. */
1935 w32_delayed_load (Lisp_Object libraries
, Lisp_Object type
)
1937 HMODULE library
= NULL
;
1939 if (CONSP (libraries
) && NILP (Fassq (type
, Vimage_type_cache
)))
1941 Lisp_Object dlls
= Fassq (type
, libraries
);
1944 for (dlls
= XCDR (dlls
); CONSP (dlls
); dlls
= XCDR (dlls
))
1946 CHECK_STRING_CAR (dlls
);
1947 if (library
= LoadLibrary (SDATA (XCAR (dlls
))))
1955 #endif /* HAVE_NTGUI */
1957 static int x_create_x_image_and_pixmap (struct frame
*, int, int, int,
1958 XImagePtr
*, Pixmap
*);
1959 static void x_destroy_x_image (XImagePtr
);
1960 static void x_put_x_image (struct frame
*, XImagePtr
, Pixmap
, int, int);
1963 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
1964 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
1965 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
1966 via xmalloc. Print error messages via image_error if an error
1967 occurs. Value is non-zero if successful.
1969 On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
1970 should indicate the bit depth of the image. */
1973 x_create_x_image_and_pixmap (struct frame
*f
, int width
, int height
, int depth
,
1974 XImagePtr
*ximg
, Pixmap
*pixmap
)
1976 #ifdef HAVE_X_WINDOWS
1977 Display
*display
= FRAME_X_DISPLAY (f
);
1978 Window window
= FRAME_X_WINDOW (f
);
1979 Screen
*screen
= FRAME_X_SCREEN (f
);
1981 xassert (interrupt_input_blocked
);
1984 depth
= DefaultDepthOfScreen (screen
);
1985 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
1986 depth
, ZPixmap
, 0, NULL
, width
, height
,
1987 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
1990 image_error ("Unable to allocate X image", Qnil
, Qnil
);
1994 /* Allocate image raster. */
1995 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
1997 /* Allocate a pixmap of the same size. */
1998 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
1999 if (*pixmap
== NO_PIXMAP
)
2001 x_destroy_x_image (*ximg
);
2003 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
2008 #endif /* HAVE_X_WINDOWS */
2012 BITMAPINFOHEADER
*header
;
2014 int scanline_width_bits
;
2016 int palette_colors
= 0;
2021 if (depth
!= 1 && depth
!= 4 && depth
!= 8
2022 && depth
!= 16 && depth
!= 24 && depth
!= 32)
2024 image_error ("Invalid image bit depth specified", Qnil
, Qnil
);
2028 scanline_width_bits
= width
* depth
;
2029 remainder
= scanline_width_bits
% 32;
2032 scanline_width_bits
+= 32 - remainder
;
2034 /* Bitmaps with a depth less than 16 need a palette. */
2035 /* BITMAPINFO structure already contains the first RGBQUAD. */
2037 palette_colors
= 1 << depth
- 1;
2039 *ximg
= xmalloc (sizeof (XImage
) + palette_colors
* sizeof (RGBQUAD
));
2042 image_error ("Unable to allocate memory for XImage", Qnil
, Qnil
);
2046 header
= &(*ximg
)->info
.bmiHeader
;
2047 memset (&(*ximg
)->info
, 0, sizeof (BITMAPINFO
));
2048 header
->biSize
= sizeof (*header
);
2049 header
->biWidth
= width
;
2050 header
->biHeight
= -height
; /* negative indicates a top-down bitmap. */
2051 header
->biPlanes
= 1;
2052 header
->biBitCount
= depth
;
2053 header
->biCompression
= BI_RGB
;
2054 header
->biClrUsed
= palette_colors
;
2056 /* TODO: fill in palette. */
2059 (*ximg
)->info
.bmiColors
[0].rgbBlue
= 0;
2060 (*ximg
)->info
.bmiColors
[0].rgbGreen
= 0;
2061 (*ximg
)->info
.bmiColors
[0].rgbRed
= 0;
2062 (*ximg
)->info
.bmiColors
[0].rgbReserved
= 0;
2063 (*ximg
)->info
.bmiColors
[1].rgbBlue
= 255;
2064 (*ximg
)->info
.bmiColors
[1].rgbGreen
= 255;
2065 (*ximg
)->info
.bmiColors
[1].rgbRed
= 255;
2066 (*ximg
)->info
.bmiColors
[1].rgbReserved
= 0;
2069 hdc
= get_frame_dc (f
);
2071 /* Create a DIBSection and raster array for the bitmap,
2072 and store its handle in *pixmap. */
2073 *pixmap
= CreateDIBSection (hdc
, &((*ximg
)->info
),
2074 (depth
< 16) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
,
2075 /* casting avoids a GCC warning */
2076 (void **)&((*ximg
)->data
), NULL
, 0);
2078 /* Realize display palette and garbage all frames. */
2079 release_frame_dc (f
, hdc
);
2081 if (*pixmap
== NULL
)
2083 DWORD err
= GetLastError ();
2084 Lisp_Object errcode
;
2085 /* All system errors are < 10000, so the following is safe. */
2086 XSETINT (errcode
, (int) err
);
2087 image_error ("Unable to create bitmap, error code %d", errcode
, Qnil
);
2088 x_destroy_x_image (*ximg
);
2094 #endif /* HAVE_NTGUI */
2097 *pixmap
= ns_image_for_XPM (width
, height
, depth
);
2101 image_error ("Unable to allocate NSImage for XPM pixmap", Qnil
, Qnil
);
2110 /* Destroy XImage XIMG. Free XIMG->data. */
2113 x_destroy_x_image (XImagePtr ximg
)
2115 xassert (interrupt_input_blocked
);
2118 #ifdef HAVE_X_WINDOWS
2121 XDestroyImage (ximg
);
2122 #endif /* HAVE_X_WINDOWS */
2124 /* Data will be freed by DestroyObject. */
2127 #endif /* HAVE_NTGUI */
2129 ns_release_object (ximg
);
2130 #endif /* HAVE_NS */
2135 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
2136 are width and height of both the image and pixmap. */
2139 x_put_x_image (struct frame
*f
, XImagePtr ximg
, Pixmap pixmap
, int width
, int height
)
2141 #ifdef HAVE_X_WINDOWS
2144 xassert (interrupt_input_blocked
);
2145 gc
= XCreateGC (FRAME_X_DISPLAY (f
), pixmap
, 0, NULL
);
2146 XPutImage (FRAME_X_DISPLAY (f
), pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
2147 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
2148 #endif /* HAVE_X_WINDOWS */
2151 #if 0 /* I don't think this is necessary looking at where it is used. */
2152 HDC hdc
= get_frame_dc (f
);
2153 SetDIBits (hdc
, pixmap
, 0, height
, ximg
->data
, &(ximg
->info
), DIB_RGB_COLORS
);
2154 release_frame_dc (f
, hdc
);
2156 #endif /* HAVE_NTGUI */
2159 xassert (ximg
== pixmap
);
2160 ns_retain_object (ximg
);
2165 /***********************************************************************
2167 ***********************************************************************/
2169 static unsigned char *slurp_file (char *, int *);
2172 /* Find image file FILE. Look in data-directory/images, then
2173 x-bitmap-file-path. Value is the encoded full name of the file
2174 found, or nil if not found. */
2177 x_find_image_file (Lisp_Object file
)
2179 Lisp_Object file_found
, search_path
;
2180 struct gcpro gcpro1
, gcpro2
;
2184 /* TODO I think this should use something like image-load-path
2185 instead. Unfortunately, that can contain non-string elements. */
2186 search_path
= Fcons (Fexpand_file_name (build_string ("images"),
2188 Vx_bitmap_file_path
);
2189 GCPRO2 (file_found
, search_path
);
2191 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
2192 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
2198 file_found
= ENCODE_FILE (file_found
);
2207 /* Read FILE into memory. Value is a pointer to a buffer allocated
2208 with xmalloc holding FILE's contents. Value is null if an error
2209 occurred. *SIZE is set to the size of the file. */
2211 static unsigned char *
2212 slurp_file (char *file
, int *size
)
2215 unsigned char *buf
= NULL
;
2218 if (stat (file
, &st
) == 0
2219 && (fp
= fopen (file
, "rb")) != NULL
2220 && (buf
= (unsigned char *) xmalloc (st
.st_size
),
2221 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
2242 /***********************************************************************
2244 ***********************************************************************/
2246 static int xbm_scan (unsigned char **, unsigned char *, char *, int *);
2247 static int xbm_load (struct frame
*f
, struct image
*img
);
2248 static int xbm_load_image (struct frame
*f
, struct image
*img
,
2249 unsigned char *, unsigned char *);
2250 static int xbm_image_p (Lisp_Object object
);
2251 static int xbm_read_bitmap_data (struct frame
*f
,
2252 unsigned char *, unsigned char *,
2253 int *, int *, unsigned char **, int);
2254 static int xbm_file_p (Lisp_Object
);
2257 /* Indices of image specification fields in xbm_format, below. */
2259 enum xbm_keyword_index
2277 /* Vector of image_keyword structures describing the format
2278 of valid XBM image specifications. */
2280 static const struct image_keyword xbm_format
[XBM_LAST
] =
2282 {":type", IMAGE_SYMBOL_VALUE
, 1},
2283 {":file", IMAGE_STRING_VALUE
, 0},
2284 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2285 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2286 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2287 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
2288 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
2289 {":ascent", IMAGE_ASCENT_VALUE
, 0},
2290 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
2291 {":relief", IMAGE_INTEGER_VALUE
, 0},
2292 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2293 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2294 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
2297 /* Structure describing the image type XBM. */
2299 static struct image_type xbm_type
=
2308 /* Tokens returned from xbm_scan. */
2317 /* Return non-zero if OBJECT is a valid XBM-type image specification.
2318 A valid specification is a list starting with the symbol `image'
2319 The rest of the list is a property list which must contain an
2322 If the specification specifies a file to load, it must contain
2323 an entry `:file FILENAME' where FILENAME is a string.
2325 If the specification is for a bitmap loaded from memory it must
2326 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
2327 WIDTH and HEIGHT are integers > 0. DATA may be:
2329 1. a string large enough to hold the bitmap data, i.e. it must
2330 have a size >= (WIDTH + 7) / 8 * HEIGHT
2332 2. a bool-vector of size >= WIDTH * HEIGHT
2334 3. a vector of strings or bool-vectors, one for each line of the
2337 4. a string containing an in-memory XBM file. WIDTH and HEIGHT
2338 may not be specified in this case because they are defined in the
2341 Both the file and data forms may contain the additional entries
2342 `:background COLOR' and `:foreground COLOR'. If not present,
2343 foreground and background of the frame on which the image is
2344 displayed is used. */
2347 xbm_image_p (Lisp_Object object
)
2349 struct image_keyword kw
[XBM_LAST
];
2351 memcpy (kw
, xbm_format
, sizeof kw
);
2352 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
2355 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
2357 if (kw
[XBM_FILE
].count
)
2359 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
2362 else if (kw
[XBM_DATA
].count
&& xbm_file_p (kw
[XBM_DATA
].value
))
2364 /* In-memory XBM file. */
2365 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_FILE
].count
)
2373 /* Entries for `:width', `:height' and `:data' must be present. */
2374 if (!kw
[XBM_WIDTH
].count
2375 || !kw
[XBM_HEIGHT
].count
2376 || !kw
[XBM_DATA
].count
)
2379 data
= kw
[XBM_DATA
].value
;
2380 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
2381 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
2383 /* Check type of data, and width and height against contents of
2389 /* Number of elements of the vector must be >= height. */
2390 if (XVECTOR (data
)->size
< height
)
2393 /* Each string or bool-vector in data must be large enough
2394 for one line of the image. */
2395 for (i
= 0; i
< height
; ++i
)
2397 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
2402 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
2405 else if (BOOL_VECTOR_P (elt
))
2407 if (XBOOL_VECTOR (elt
)->size
< width
)
2414 else if (STRINGP (data
))
2417 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
2420 else if (BOOL_VECTOR_P (data
))
2422 if (XBOOL_VECTOR (data
)->size
< width
* height
)
2433 /* Scan a bitmap file. FP is the stream to read from. Value is
2434 either an enumerator from enum xbm_token, or a character for a
2435 single-character token, or 0 at end of file. If scanning an
2436 identifier, store the lexeme of the identifier in SVAL. If
2437 scanning a number, store its value in *IVAL. */
2440 xbm_scan (unsigned char **s
, unsigned char *end
, char *sval
, int *ival
)
2446 /* Skip white space. */
2447 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
2452 else if (isdigit (c
))
2454 int value
= 0, digit
;
2456 if (c
== '0' && *s
< end
)
2459 if (c
== 'x' || c
== 'X')
2466 else if (c
>= 'a' && c
<= 'f')
2467 digit
= c
- 'a' + 10;
2468 else if (c
>= 'A' && c
<= 'F')
2469 digit
= c
- 'A' + 10;
2472 value
= 16 * value
+ digit
;
2475 else if (isdigit (c
))
2479 && (c
= *(*s
)++, isdigit (c
)))
2480 value
= 8 * value
+ c
- '0';
2487 && (c
= *(*s
)++, isdigit (c
)))
2488 value
= 10 * value
+ c
- '0';
2496 else if (isalpha (c
) || c
== '_')
2500 && (c
= *(*s
)++, (isalnum (c
) || c
== '_')))
2507 else if (c
== '/' && **s
== '*')
2509 /* C-style comment. */
2511 while (**s
&& (**s
!= '*' || *(*s
+ 1) != '/'))
2525 /* Create a Windows bitmap from X bitmap data. */
2527 w32_create_pixmap_from_bitmap_data (int width
, int height
, char *data
)
2529 static unsigned char swap_nibble
[16]
2530 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
2531 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
2532 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
2533 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
2535 unsigned char *bits
, *p
;
2538 w1
= (width
+ 7) / 8; /* nb of 8bits elt in X bitmap */
2539 w2
= ((width
+ 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
2540 bits
= (unsigned char *) alloca (height
* w2
);
2541 memset (bits
, 0, height
* w2
);
2542 for (i
= 0; i
< height
; i
++)
2545 for (j
= 0; j
< w1
; j
++)
2547 /* Bitswap XBM bytes to match how Windows does things. */
2548 unsigned char c
= *data
++;
2549 *p
++ = (unsigned char)((swap_nibble
[c
& 0xf] << 4)
2550 | (swap_nibble
[(c
>>4) & 0xf]));
2553 bmp
= CreateBitmap (width
, height
, 1, 1, (char *) bits
);
2559 convert_mono_to_color_image (f
, img
, foreground
, background
)
2562 COLORREF foreground
, background
;
2564 HDC hdc
, old_img_dc
, new_img_dc
;
2565 HGDIOBJ old_prev
, new_prev
;
2568 hdc
= get_frame_dc (f
);
2569 old_img_dc
= CreateCompatibleDC (hdc
);
2570 new_img_dc
= CreateCompatibleDC (hdc
);
2571 new_pixmap
= CreateCompatibleBitmap (hdc
, img
->width
, img
->height
);
2572 release_frame_dc (f
, hdc
);
2573 old_prev
= SelectObject (old_img_dc
, img
->pixmap
);
2574 new_prev
= SelectObject (new_img_dc
, new_pixmap
);
2575 /* Windows convention for mono bitmaps is black = background,
2576 white = foreground. */
2577 SetTextColor (new_img_dc
, background
);
2578 SetBkColor (new_img_dc
, foreground
);
2580 BitBlt (new_img_dc
, 0, 0, img
->width
, img
->height
, old_img_dc
,
2583 SelectObject (old_img_dc
, old_prev
);
2584 SelectObject (new_img_dc
, new_prev
);
2585 DeleteDC (old_img_dc
);
2586 DeleteDC (new_img_dc
);
2587 DeleteObject (img
->pixmap
);
2588 if (new_pixmap
== 0)
2589 fprintf (stderr
, "Failed to convert image to color.\n");
2591 img
->pixmap
= new_pixmap
;
2594 #define XBM_BIT_SHUFFLE(b) (~(b))
2598 #define XBM_BIT_SHUFFLE(b) (b)
2600 #endif /* HAVE_NTGUI */
2604 Create_Pixmap_From_Bitmap_Data (struct frame
*f
, struct image
*img
, char *data
,
2605 RGB_PIXEL_COLOR fg
, RGB_PIXEL_COLOR bg
,
2606 int non_default_colors
)
2610 = w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
, data
);
2612 /* If colors were specified, transfer the bitmap to a color one. */
2613 if (non_default_colors
)
2614 convert_mono_to_color_image (f
, img
, fg
, bg
);
2616 #elif defined (HAVE_NS)
2617 img
->pixmap
= ns_image_from_XBM (data
, img
->width
, img
->height
);
2621 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
2624 img
->width
, img
->height
,
2626 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
2627 #endif /* !HAVE_NTGUI && !HAVE_NS */
2632 /* Replacement for XReadBitmapFileData which isn't available under old
2633 X versions. CONTENTS is a pointer to a buffer to parse; END is the
2634 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
2635 the image. Return in *DATA the bitmap data allocated with xmalloc.
2636 Value is non-zero if successful. DATA null means just test if
2637 CONTENTS looks like an in-memory XBM file. If INHIBIT_IMAGE_ERROR
2638 is non-zero, inhibit the call to image_error when the image size is
2639 invalid (the bitmap remains unread). */
2642 xbm_read_bitmap_data (struct frame
*f
, unsigned char *contents
, unsigned char *end
,
2643 int *width
, int *height
, unsigned char **data
,
2644 int inhibit_image_error
)
2646 unsigned char *s
= contents
;
2647 char buffer
[BUFSIZ
];
2650 int bytes_per_line
, i
, nbytes
;
2656 LA1 = xbm_scan (&s, end, buffer, &value)
2658 #define expect(TOKEN) \
2659 if (LA1 != (TOKEN)) \
2664 #define expect_ident(IDENT) \
2665 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
2670 *width
= *height
= -1;
2673 LA1
= xbm_scan (&s
, end
, buffer
, &value
);
2675 /* Parse defines for width, height and hot-spots. */
2679 expect_ident ("define");
2680 expect (XBM_TK_IDENT
);
2682 if (LA1
== XBM_TK_NUMBER
)
2684 char *p
= strrchr (buffer
, '_');
2685 p
= p
? p
+ 1 : buffer
;
2686 if (strcmp (p
, "width") == 0)
2688 else if (strcmp (p
, "height") == 0)
2691 expect (XBM_TK_NUMBER
);
2694 if (!check_image_size (f
, *width
, *height
))
2696 if (!inhibit_image_error
)
2697 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
2700 else if (data
== NULL
)
2703 /* Parse bits. Must start with `static'. */
2704 expect_ident ("static");
2705 if (LA1
== XBM_TK_IDENT
)
2707 if (strcmp (buffer
, "unsigned") == 0)
2710 expect_ident ("char");
2712 else if (strcmp (buffer
, "short") == 0)
2716 if (*width
% 16 && *width
% 16 < 9)
2719 else if (strcmp (buffer
, "char") == 0)
2727 expect (XBM_TK_IDENT
);
2733 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
2734 nbytes
= bytes_per_line
* *height
;
2735 p
= *data
= (unsigned char *) xmalloc (nbytes
);
2739 for (i
= 0; i
< nbytes
; i
+= 2)
2742 expect (XBM_TK_NUMBER
);
2744 *p
++ = XBM_BIT_SHUFFLE (val
);
2745 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
2746 *p
++ = XBM_BIT_SHUFFLE (value
>> 8);
2748 if (LA1
== ',' || LA1
== '}')
2756 for (i
= 0; i
< nbytes
; ++i
)
2759 expect (XBM_TK_NUMBER
);
2761 *p
++ = XBM_BIT_SHUFFLE (val
);
2763 if (LA1
== ',' || LA1
== '}')
2788 /* Load XBM image IMG which will be displayed on frame F from buffer
2789 CONTENTS. END is the end of the buffer. Value is non-zero if
2793 xbm_load_image (struct frame
*f
, struct image
*img
, unsigned char *contents
,
2797 unsigned char *data
;
2800 rc
= xbm_read_bitmap_data (f
, contents
, end
, &img
->width
, &img
->height
,
2804 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2805 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2806 int non_default_colors
= 0;
2809 xassert (img
->width
> 0 && img
->height
> 0);
2811 /* Get foreground and background colors, maybe allocate colors. */
2812 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
2815 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
2816 non_default_colors
= 1;
2818 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
2821 background
= x_alloc_image_color (f
, img
, value
, background
);
2822 img
->background
= background
;
2823 img
->background_valid
= 1;
2824 non_default_colors
= 1;
2827 Create_Pixmap_From_Bitmap_Data (f
, img
, data
,
2828 foreground
, background
,
2829 non_default_colors
);
2832 if (img
->pixmap
== NO_PIXMAP
)
2834 x_clear_image (f
, img
);
2835 image_error ("Unable to create X pixmap for `%s'", img
->spec
, Qnil
);
2841 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
2847 /* Value is non-zero if DATA looks like an in-memory XBM file. */
2850 xbm_file_p (Lisp_Object data
)
2853 return (STRINGP (data
)
2854 && xbm_read_bitmap_data (NULL
, SDATA (data
),
2855 (SDATA (data
) + SBYTES (data
)),
2860 /* Fill image IMG which is used on frame F with pixmap data. Value is
2861 non-zero if successful. */
2864 xbm_load (struct frame
*f
, struct image
*img
)
2867 Lisp_Object file_name
;
2869 xassert (xbm_image_p (img
->spec
));
2871 /* If IMG->spec specifies a file name, create a non-file spec from it. */
2872 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
2873 if (STRINGP (file_name
))
2876 unsigned char *contents
;
2878 struct gcpro gcpro1
;
2880 file
= x_find_image_file (file_name
);
2882 if (!STRINGP (file
))
2884 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
2889 contents
= slurp_file (SDATA (file
), &size
);
2890 if (contents
== NULL
)
2892 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
2897 success_p
= xbm_load_image (f
, img
, contents
, contents
+ size
);
2902 struct image_keyword fmt
[XBM_LAST
];
2904 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2905 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2906 int non_default_colors
= 0;
2909 int in_memory_file_p
= 0;
2911 /* See if data looks like an in-memory XBM file. */
2912 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
2913 in_memory_file_p
= xbm_file_p (data
);
2915 /* Parse the image specification. */
2916 memcpy (fmt
, xbm_format
, sizeof fmt
);
2917 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
2920 /* Get specified width, and height. */
2921 if (!in_memory_file_p
)
2923 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
2924 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
2925 xassert (img
->width
> 0 && img
->height
> 0);
2928 /* Get foreground and background colors, maybe allocate colors. */
2929 if (fmt
[XBM_FOREGROUND
].count
2930 && STRINGP (fmt
[XBM_FOREGROUND
].value
))
2932 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
2934 non_default_colors
= 1;
2937 if (fmt
[XBM_BACKGROUND
].count
2938 && STRINGP (fmt
[XBM_BACKGROUND
].value
))
2940 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
2942 non_default_colors
= 1;
2945 if (in_memory_file_p
)
2946 success_p
= xbm_load_image (f
, img
, SDATA (data
),
2955 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
2957 p
= bits
= (char *) alloca (nbytes
* img
->height
);
2958 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
2960 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
2962 memcpy (p
, SDATA (line
), nbytes
);
2964 memcpy (p
, XBOOL_VECTOR (line
)->data
, nbytes
);
2967 else if (STRINGP (data
))
2968 bits
= SDATA (data
);
2970 bits
= XBOOL_VECTOR (data
)->data
;
2976 /* Windows mono bitmaps are reversed compared with X. */
2977 invertedBits
= bits
;
2978 nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
2980 bits
= (char *) alloca (nbytes
);
2981 for (i
= 0; i
< nbytes
; i
++)
2982 bits
[i
] = XBM_BIT_SHUFFLE (invertedBits
[i
]);
2985 /* Create the pixmap. */
2987 Create_Pixmap_From_Bitmap_Data (f
, img
, bits
,
2988 foreground
, background
,
2989 non_default_colors
);
2994 image_error ("Unable to create pixmap for XBM image `%s'",
2996 x_clear_image (f
, img
);
3006 /***********************************************************************
3008 ***********************************************************************/
3010 #if defined (HAVE_XPM) || defined (HAVE_NS)
3012 static int xpm_image_p (Lisp_Object object
);
3013 static int xpm_load (struct frame
*f
, struct image
*img
);
3014 static int xpm_valid_color_symbols_p (Lisp_Object
);
3016 #endif /* HAVE_XPM || HAVE_NS */
3020 /* Indicate to xpm.h that we don't have Xlib. */
3022 /* simx.h in xpm defines XColor and XImage differently than Emacs. */
3023 /* It also defines Display the same way as Emacs, but gcc 3.3 still barfs. */
3024 #define XColor xpm_XColor
3025 #define XImage xpm_XImage
3026 #define Display xpm_Display
3027 #define PIXEL_ALREADY_TYPEDEFED
3028 #include "X11/xpm.h"
3033 #undef PIXEL_ALREADY_TYPEDEFED
3035 #include "X11/xpm.h"
3036 #endif /* HAVE_NTGUI */
3037 #endif /* HAVE_XPM */
3039 #if defined (HAVE_XPM) || defined (HAVE_NS)
3040 /* The symbol `xpm' identifying XPM-format images. */
3044 /* Indices of image specification fields in xpm_format, below. */
3046 enum xpm_keyword_index
3062 /* Vector of image_keyword structures describing the format
3063 of valid XPM image specifications. */
3065 static const struct image_keyword xpm_format
[XPM_LAST
] =
3067 {":type", IMAGE_SYMBOL_VALUE
, 1},
3068 {":file", IMAGE_STRING_VALUE
, 0},
3069 {":data", IMAGE_STRING_VALUE
, 0},
3070 {":ascent", IMAGE_ASCENT_VALUE
, 0},
3071 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
3072 {":relief", IMAGE_INTEGER_VALUE
, 0},
3073 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3074 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3075 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3076 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3077 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
3080 /* Structure describing the image type XPM. */
3082 static struct image_type xpm_type
=
3091 #ifdef HAVE_X_WINDOWS
3093 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
3094 functions for allocating image colors. Our own functions handle
3095 color allocation failures more gracefully than the ones on the XPM
3098 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
3099 #define ALLOC_XPM_COLORS
3101 #endif /* HAVE_X_WINDOWS */
3103 #ifdef ALLOC_XPM_COLORS
3105 static void xpm_init_color_cache (struct frame
*, XpmAttributes
*);
3106 static void xpm_free_color_cache (void);
3107 static int xpm_lookup_color (struct frame
*, char *, XColor
*);
3108 static int xpm_color_bucket (char *);
3109 static struct xpm_cached_color
*xpm_cache_color (struct frame
*, char *,
3112 /* An entry in a hash table used to cache color definitions of named
3113 colors. This cache is necessary to speed up XPM image loading in
3114 case we do color allocations ourselves. Without it, we would need
3115 a call to XParseColor per pixel in the image. */
3117 struct xpm_cached_color
3119 /* Next in collision chain. */
3120 struct xpm_cached_color
*next
;
3122 /* Color definition (RGB and pixel color). */
3129 /* The hash table used for the color cache, and its bucket vector
3132 #define XPM_COLOR_CACHE_BUCKETS 1001
3133 struct xpm_cached_color
**xpm_color_cache
;
3135 /* Initialize the color cache. */
3138 xpm_init_color_cache (struct frame
*f
, XpmAttributes
*attrs
)
3140 size_t nbytes
= XPM_COLOR_CACHE_BUCKETS
* sizeof *xpm_color_cache
;
3141 xpm_color_cache
= (struct xpm_cached_color
**) xmalloc (nbytes
);
3142 memset (xpm_color_cache
, 0, nbytes
);
3143 init_color_table ();
3145 if (attrs
->valuemask
& XpmColorSymbols
)
3150 for (i
= 0; i
< attrs
->numsymbols
; ++i
)
3151 if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
3152 attrs
->colorsymbols
[i
].value
, &color
))
3154 color
.pixel
= lookup_rgb_color (f
, color
.red
, color
.green
,
3156 xpm_cache_color (f
, attrs
->colorsymbols
[i
].name
, &color
, -1);
3161 /* Free the color cache. */
3164 xpm_free_color_cache (void)
3166 struct xpm_cached_color
*p
, *next
;
3169 for (i
= 0; i
< XPM_COLOR_CACHE_BUCKETS
; ++i
)
3170 for (p
= xpm_color_cache
[i
]; p
; p
= next
)
3176 xfree (xpm_color_cache
);
3177 xpm_color_cache
= NULL
;
3178 free_color_table ();
3181 /* Return the bucket index for color named COLOR_NAME in the color
3185 xpm_color_bucket (char *color_name
)
3190 for (s
= color_name
; *s
; ++s
)
3192 return h
%= XPM_COLOR_CACHE_BUCKETS
;
3196 /* On frame F, cache values COLOR for color with name COLOR_NAME.
3197 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
3200 static struct xpm_cached_color
*
3201 xpm_cache_color (struct frame
*f
, char *color_name
, XColor
*color
, int bucket
)
3204 struct xpm_cached_color
*p
;
3207 bucket
= xpm_color_bucket (color_name
);
3209 nbytes
= sizeof *p
+ strlen (color_name
);
3210 p
= (struct xpm_cached_color
*) xmalloc (nbytes
);
3211 strcpy (p
->name
, color_name
);
3213 p
->next
= xpm_color_cache
[bucket
];
3214 xpm_color_cache
[bucket
] = p
;
3218 /* Look up color COLOR_NAME for frame F in the color cache. If found,
3219 return the cached definition in *COLOR. Otherwise, make a new
3220 entry in the cache and allocate the color. Value is zero if color
3221 allocation failed. */
3224 xpm_lookup_color (struct frame
*f
, char *color_name
, XColor
*color
)
3226 struct xpm_cached_color
*p
;
3227 int h
= xpm_color_bucket (color_name
);
3229 for (p
= xpm_color_cache
[h
]; p
; p
= p
->next
)
3230 if (strcmp (p
->name
, color_name
) == 0)
3235 else if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
3238 color
->pixel
= lookup_rgb_color (f
, color
->red
, color
->green
,
3240 p
= xpm_cache_color (f
, color_name
, color
, h
);
3242 /* You get `opaque' at least from ImageMagick converting pbm to xpm
3243 with transparency, and it's useful. */
3244 else if (strcmp ("opaque", color_name
) == 0)
3246 memset (color
, 0, sizeof (XColor
)); /* Is this necessary/correct? */
3247 color
->pixel
= FRAME_FOREGROUND_PIXEL (f
);
3248 p
= xpm_cache_color (f
, color_name
, color
, h
);
3255 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
3256 CLOSURE is a pointer to the frame on which we allocate the
3257 color. Return in *COLOR the allocated color. Value is non-zero
3261 xpm_alloc_color (Display
*dpy
, Colormap cmap
, char *color_name
, XColor
*color
,
3264 return xpm_lookup_color ((struct frame
*) closure
, color_name
, color
);
3268 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
3269 is a pointer to the frame on which we allocate the color. Value is
3270 non-zero if successful. */
3273 xpm_free_colors (Display
*dpy
, Colormap cmap
, Pixel
*pixels
, int npixels
, void *closure
)
3278 #endif /* ALLOC_XPM_COLORS */
3283 /* XPM library details. */
3285 DEF_IMGLIB_FN (XpmFreeAttributes
);
3286 DEF_IMGLIB_FN (XpmCreateImageFromBuffer
);
3287 DEF_IMGLIB_FN (XpmReadFileToImage
);
3288 DEF_IMGLIB_FN (XImageFree
);
3291 init_xpm_functions (Lisp_Object libraries
)
3295 if (!(library
= w32_delayed_load (libraries
, Qxpm
)))
3298 LOAD_IMGLIB_FN (library
, XpmFreeAttributes
);
3299 LOAD_IMGLIB_FN (library
, XpmCreateImageFromBuffer
);
3300 LOAD_IMGLIB_FN (library
, XpmReadFileToImage
);
3301 LOAD_IMGLIB_FN (library
, XImageFree
);
3305 #endif /* HAVE_NTGUI */
3308 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
3309 for XPM images. Such a list must consist of conses whose car and
3313 xpm_valid_color_symbols_p (Lisp_Object color_symbols
)
3315 while (CONSP (color_symbols
))
3317 Lisp_Object sym
= XCAR (color_symbols
);
3319 || !STRINGP (XCAR (sym
))
3320 || !STRINGP (XCDR (sym
)))
3322 color_symbols
= XCDR (color_symbols
);
3325 return NILP (color_symbols
);
3329 /* Value is non-zero if OBJECT is a valid XPM image specification. */
3332 xpm_image_p (Lisp_Object object
)
3334 struct image_keyword fmt
[XPM_LAST
];
3335 memcpy (fmt
, xpm_format
, sizeof fmt
);
3336 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
3337 /* Either `:file' or `:data' must be present. */
3338 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
3339 /* Either no `:color-symbols' or it's a list of conses
3340 whose car and cdr are strings. */
3341 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
3342 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
)));
3345 #endif /* HAVE_XPM || HAVE_NS */
3347 #if defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
3349 x_create_bitmap_from_xpm_data (struct frame
*f
, char **bits
)
3351 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3353 XpmAttributes attrs
;
3354 Pixmap bitmap
, mask
;
3356 memset (&attrs
, 0, sizeof attrs
);
3358 attrs
.visual
= FRAME_X_VISUAL (f
);
3359 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3360 attrs
.valuemask
|= XpmVisual
;
3361 attrs
.valuemask
|= XpmColormap
;
3363 rc
= XpmCreatePixmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3364 bits
, &bitmap
, &mask
, &attrs
);
3365 if (rc
!= XpmSuccess
)
3367 XpmFreeAttributes (&attrs
);
3371 id
= x_allocate_bitmap_record (f
);
3372 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
3373 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
3374 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
3375 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
3376 dpyinfo
->bitmaps
[id
- 1].height
= attrs
.height
;
3377 dpyinfo
->bitmaps
[id
- 1].width
= attrs
.width
;
3378 dpyinfo
->bitmaps
[id
- 1].depth
= attrs
.depth
;
3379 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
3381 XpmFreeAttributes (&attrs
);
3384 #endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */
3386 /* Load image IMG which will be displayed on frame F. Value is
3387 non-zero if successful. */
3392 xpm_load (struct frame
*f
, struct image
*img
)
3395 XpmAttributes attrs
;
3396 Lisp_Object specified_file
, color_symbols
;
3399 xpm_XImage
* xpm_image
= NULL
, * xpm_mask
= NULL
;
3400 #endif /* HAVE_NTGUI */
3402 /* Configure the XPM lib. Use the visual of frame F. Allocate
3403 close colors. Return colors allocated. */
3404 memset (&attrs
, 0, sizeof attrs
);
3407 attrs
.visual
= FRAME_X_VISUAL (f
);
3408 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3409 attrs
.valuemask
|= XpmVisual
;
3410 attrs
.valuemask
|= XpmColormap
;
3411 #endif /* HAVE_NTGUI */
3413 #ifdef ALLOC_XPM_COLORS
3414 /* Allocate colors with our own functions which handle
3415 failing color allocation more gracefully. */
3416 attrs
.color_closure
= f
;
3417 attrs
.alloc_color
= xpm_alloc_color
;
3418 attrs
.free_colors
= xpm_free_colors
;
3419 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
3420 #else /* not ALLOC_XPM_COLORS */
3421 /* Let the XPM lib allocate colors. */
3422 attrs
.valuemask
|= XpmReturnAllocPixels
;
3423 #ifdef XpmAllocCloseColors
3424 attrs
.alloc_close_colors
= 1;
3425 attrs
.valuemask
|= XpmAllocCloseColors
;
3426 #else /* not XpmAllocCloseColors */
3427 attrs
.closeness
= 600;
3428 attrs
.valuemask
|= XpmCloseness
;
3429 #endif /* not XpmAllocCloseColors */
3430 #endif /* ALLOC_XPM_COLORS */
3432 /* If image specification contains symbolic color definitions, add
3433 these to `attrs'. */
3434 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
3435 if (CONSP (color_symbols
))
3438 XpmColorSymbol
*xpm_syms
;
3441 attrs
.valuemask
|= XpmColorSymbols
;
3443 /* Count number of symbols. */
3444 attrs
.numsymbols
= 0;
3445 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
3448 /* Allocate an XpmColorSymbol array. */
3449 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
3450 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
3451 memset (xpm_syms
, 0, size
);
3452 attrs
.colorsymbols
= xpm_syms
;
3454 /* Fill the color symbol array. */
3455 for (tail
= color_symbols
, i
= 0;
3457 ++i
, tail
= XCDR (tail
))
3459 Lisp_Object name
= XCAR (XCAR (tail
));
3460 Lisp_Object color
= XCDR (XCAR (tail
));
3461 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
3462 strcpy (xpm_syms
[i
].name
, SDATA (name
));
3463 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
3464 strcpy (xpm_syms
[i
].value
, SDATA (color
));
3468 /* Create a pixmap for the image, either from a file, or from a
3469 string buffer containing data in the same format as an XPM file. */
3470 #ifdef ALLOC_XPM_COLORS
3471 xpm_init_color_cache (f
, &attrs
);
3474 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
3478 HDC frame_dc
= get_frame_dc (f
);
3479 hdc
= CreateCompatibleDC (frame_dc
);
3480 release_frame_dc (f
, frame_dc
);
3482 #endif /* HAVE_NTGUI */
3484 if (STRINGP (specified_file
))
3486 Lisp_Object file
= x_find_image_file (specified_file
);
3487 if (!STRINGP (file
))
3489 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
3494 /* XpmReadFileToPixmap is not available in the Windows port of
3495 libxpm. But XpmReadFileToImage almost does what we want. */
3496 rc
= fn_XpmReadFileToImage (&hdc
, SDATA (file
),
3497 &xpm_image
, &xpm_mask
,
3500 rc
= XpmReadFileToPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3501 SDATA (file
), &img
->pixmap
, &img
->mask
,
3503 #endif /* HAVE_NTGUI */
3507 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
3509 /* XpmCreatePixmapFromBuffer is not available in the Windows port
3510 of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
3511 rc
= fn_XpmCreateImageFromBuffer (&hdc
, SDATA (buffer
),
3512 &xpm_image
, &xpm_mask
,
3515 rc
= XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3517 &img
->pixmap
, &img
->mask
,
3519 #endif /* HAVE_NTGUI */
3522 if (rc
== XpmSuccess
)
3524 #if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS)
3525 img
->colors
= colors_in_color_table (&img
->ncolors
);
3526 #else /* not ALLOC_XPM_COLORS */
3530 /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
3531 plus some duplicate attributes. */
3532 if (xpm_image
&& xpm_image
->bitmap
)
3534 img
->pixmap
= xpm_image
->bitmap
;
3535 /* XImageFree in libXpm frees XImage struct without destroying
3536 the bitmap, which is what we want. */
3537 fn_XImageFree (xpm_image
);
3539 if (xpm_mask
&& xpm_mask
->bitmap
)
3541 /* The mask appears to be inverted compared with what we expect.
3542 TODO: invert our expectations. See other places where we
3543 have to invert bits because our idea of masks is backwards. */
3545 old_obj
= SelectObject (hdc
, xpm_mask
->bitmap
);
3547 PatBlt (hdc
, 0, 0, xpm_mask
->width
, xpm_mask
->height
, DSTINVERT
);
3548 SelectObject (hdc
, old_obj
);
3550 img
->mask
= xpm_mask
->bitmap
;
3551 fn_XImageFree (xpm_mask
);
3556 #endif /* HAVE_NTGUI */
3558 /* Remember allocated colors. */
3559 img
->ncolors
= attrs
.nalloc_pixels
;
3560 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
3561 * sizeof *img
->colors
);
3562 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
3564 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
3565 #ifdef DEBUG_X_COLORS
3566 register_color (img
->colors
[i
]);
3569 #endif /* not ALLOC_XPM_COLORS */
3571 img
->width
= attrs
.width
;
3572 img
->height
= attrs
.height
;
3573 xassert (img
->width
> 0 && img
->height
> 0);
3575 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
3577 fn_XpmFreeAttributes (&attrs
);
3579 XpmFreeAttributes (&attrs
);
3580 #endif /* HAVE_NTGUI */
3586 #endif /* HAVE_NTGUI */
3591 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
3594 case XpmFileInvalid
:
3595 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
3599 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
3602 case XpmColorFailed
:
3603 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
3607 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
3612 #ifdef ALLOC_XPM_COLORS
3613 xpm_free_color_cache ();
3615 return rc
== XpmSuccess
;
3618 #endif /* HAVE_XPM */
3620 #if defined (HAVE_NS) && !defined (HAVE_XPM)
3622 /* XPM support functions for NS where libxpm is not available.
3623 Only XPM version 3 (without any extensions) is supported. */
3625 static int xpm_scan (const unsigned char **, const unsigned char *,
3626 const unsigned char **, int *);
3627 static Lisp_Object xpm_make_color_table_v
3628 (void (**) (Lisp_Object
, const unsigned char *, int, Lisp_Object
),
3629 Lisp_Object (**) (Lisp_Object
, const unsigned char *, int));
3630 static void xpm_put_color_table_v (Lisp_Object
, const unsigned char *,
3632 static Lisp_Object
xpm_get_color_table_v (Lisp_Object
,
3633 const unsigned char *, int);
3634 static Lisp_Object xpm_make_color_table_h
3635 (void (**) (Lisp_Object
, const unsigned char *, int, Lisp_Object
),
3636 Lisp_Object (**) (Lisp_Object
, const unsigned char *, int));
3637 static void xpm_put_color_table_h (Lisp_Object
, const unsigned char *,
3639 static Lisp_Object
xpm_get_color_table_h (Lisp_Object
,
3640 const unsigned char *, int);
3641 static int xpm_str_to_color_key (const char *);
3642 static int xpm_load_image (struct frame
*, struct image
*,
3643 const unsigned char *, const unsigned char *);
3645 /* Tokens returned from xpm_scan. */
3654 /* Scan an XPM data and return a character (< 256) or a token defined
3655 by enum xpm_token above. *S and END are the start (inclusive) and
3656 the end (exclusive) addresses of the data, respectively. Advance
3657 *S while scanning. If token is either XPM_TK_IDENT or
3658 XPM_TK_STRING, *BEG and *LEN are set to the start address and the
3659 length of the corresponding token, respectively. */
3662 xpm_scan (s
, end
, beg
, len
)
3663 const unsigned char **s
, *end
, **beg
;
3670 /* Skip white-space. */
3671 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
3674 /* gnus-pointer.xpm uses '-' in its identifier.
3675 sb-dir-plus.xpm uses '+' in its identifier. */
3676 if (isalpha (c
) || c
== '_' || c
== '-' || c
== '+')
3680 && (c
= **s
, isalnum (c
) || c
== '_' || c
== '-' || c
== '+'))
3683 return XPM_TK_IDENT
;
3688 while (*s
< end
&& **s
!= '"')
3693 return XPM_TK_STRING
;
3697 if (*s
< end
&& **s
== '*')
3699 /* C-style comment. */
3703 while (*s
< end
&& *(*s
)++ != '*')
3706 while (*s
< end
&& **s
!= '/');
3720 /* Functions for color table lookup in XPM data. A key is a string
3721 specifying the color of each pixel in XPM data. A value is either
3722 an integer that specifies a pixel color, Qt that specifies
3723 transparency, or Qnil for the unspecified color. If the length of
3724 the key string is one, a vector is used as a table. Otherwise, a
3725 hash table is used. */
3728 xpm_make_color_table_v (put_func
, get_func
)
3729 void (**put_func
) (Lisp_Object
, const unsigned char *, int, Lisp_Object
);
3730 Lisp_Object (**get_func
) (Lisp_Object
, const unsigned char *, int);
3732 *put_func
= xpm_put_color_table_v
;
3733 *get_func
= xpm_get_color_table_v
;
3734 return Fmake_vector (make_number (256), Qnil
);
3738 xpm_put_color_table_v (color_table
, chars_start
, chars_len
, color
)
3739 Lisp_Object color_table
;
3740 const unsigned char *chars_start
;
3744 XVECTOR (color_table
)->contents
[*chars_start
] = color
;
3748 xpm_get_color_table_v (color_table
, chars_start
, chars_len
)
3749 Lisp_Object color_table
;
3750 const unsigned char *chars_start
;
3753 return XVECTOR (color_table
)->contents
[*chars_start
];
3757 xpm_make_color_table_h (put_func
, get_func
)
3758 void (**put_func
) (Lisp_Object
, const unsigned char *, int, Lisp_Object
);
3759 Lisp_Object (**get_func
) (Lisp_Object
, const unsigned char *, int);
3761 *put_func
= xpm_put_color_table_h
;
3762 *get_func
= xpm_get_color_table_h
;
3763 return make_hash_table (Qequal
, make_number (DEFAULT_HASH_SIZE
),
3764 make_float (DEFAULT_REHASH_SIZE
),
3765 make_float (DEFAULT_REHASH_THRESHOLD
),
3770 xpm_put_color_table_h (color_table
, chars_start
, chars_len
, color
)
3771 Lisp_Object color_table
;
3772 const unsigned char *chars_start
;
3776 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
3778 Lisp_Object chars
= make_unibyte_string (chars_start
, chars_len
);
3780 hash_lookup (table
, chars
, &hash_code
);
3781 hash_put (table
, chars
, color
, hash_code
);
3785 xpm_get_color_table_h (color_table
, chars_start
, chars_len
)
3786 Lisp_Object color_table
;
3787 const unsigned char *chars_start
;
3790 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
3791 int i
= hash_lookup (table
, make_unibyte_string (chars_start
, chars_len
),
3794 return i
>= 0 ? HASH_VALUE (table
, i
) : Qnil
;
3797 enum xpm_color_key
{
3805 static const char xpm_color_key_strings
[][4] = {"s", "m", "g4", "g", "c"};
3808 xpm_str_to_color_key (s
)
3814 i
< sizeof xpm_color_key_strings
/ sizeof xpm_color_key_strings
[0];
3816 if (strcmp (xpm_color_key_strings
[i
], s
) == 0)
3822 xpm_load_image (f
, img
, contents
, end
)
3825 const unsigned char *contents
, *end
;
3827 const unsigned char *s
= contents
, *beg
, *str
;
3828 unsigned char buffer
[BUFSIZ
];
3829 int width
, height
, x
, y
;
3830 int num_colors
, chars_per_pixel
;
3832 void (*put_color_table
) (Lisp_Object
, const unsigned char *, int, Lisp_Object
);
3833 Lisp_Object (*get_color_table
) (Lisp_Object
, const unsigned char *, int);
3834 Lisp_Object frame
, color_symbols
, color_table
;
3835 int best_key
, have_mask
= 0;
3836 XImagePtr ximg
= NULL
, mask_img
= NULL
;
3839 LA1 = xpm_scan (&s, end, &beg, &len)
3841 #define expect(TOKEN) \
3842 if (LA1 != (TOKEN)) \
3847 #define expect_ident(IDENT) \
3848 if (LA1 == XPM_TK_IDENT \
3849 && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
3854 if (!(end
- s
>= 9 && memcmp (s
, "/* XPM */", 9) == 0))
3858 expect_ident ("static");
3859 expect_ident ("char");
3861 expect (XPM_TK_IDENT
);
3866 expect (XPM_TK_STRING
);
3869 memcpy (buffer
, beg
, len
);
3871 if (sscanf (buffer
, "%d %d %d %d", &width
, &height
,
3872 &num_colors
, &chars_per_pixel
) != 4
3873 || width
<= 0 || height
<= 0
3874 || num_colors
<= 0 || chars_per_pixel
<= 0)
3877 if (!check_image_size (f
, width
, height
))
3879 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
3885 XSETFRAME (frame
, f
);
3886 if (!NILP (Fxw_display_color_p (frame
)))
3887 best_key
= XPM_COLOR_KEY_C
;
3888 else if (!NILP (Fx_display_grayscale_p (frame
)))
3889 best_key
= (XFASTINT (Fx_display_planes (frame
)) > 2
3890 ? XPM_COLOR_KEY_G
: XPM_COLOR_KEY_G4
);
3892 best_key
= XPM_COLOR_KEY_M
;
3894 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
3895 if (chars_per_pixel
== 1)
3896 color_table
= xpm_make_color_table_v (&put_color_table
,
3899 color_table
= xpm_make_color_table_h (&put_color_table
,
3902 while (num_colors
-- > 0)
3904 unsigned char *color
, *max_color
;
3905 int key
, next_key
, max_key
= 0;
3906 Lisp_Object symbol_color
= Qnil
, color_val
;
3909 expect (XPM_TK_STRING
);
3910 if (len
<= chars_per_pixel
|| len
>= BUFSIZ
+ chars_per_pixel
)
3912 memcpy (buffer
, beg
+ chars_per_pixel
, len
- chars_per_pixel
);
3913 buffer
[len
- chars_per_pixel
] = '\0';
3915 str
= strtok (buffer
, " \t");
3918 key
= xpm_str_to_color_key (str
);
3923 color
= strtok (NULL
, " \t");
3927 while ((str
= strtok (NULL
, " \t")) != NULL
)
3929 next_key
= xpm_str_to_color_key (str
);
3932 color
[strlen (color
)] = ' ';
3935 if (key
== XPM_COLOR_KEY_S
)
3937 if (NILP (symbol_color
))
3938 symbol_color
= build_string (color
);
3940 else if (max_key
< key
&& key
<= best_key
)
3950 if (!NILP (color_symbols
) && !NILP (symbol_color
))
3952 Lisp_Object specified_color
= Fassoc (symbol_color
, color_symbols
);
3954 if (CONSP (specified_color
) && STRINGP (XCDR (specified_color
)))
3956 if (xstrcasecmp (SDATA (XCDR (specified_color
)), "None") == 0)
3958 else if (x_defined_color (f
, SDATA (XCDR (specified_color
)),
3960 color_val
= make_number (cdef
.pixel
);
3963 if (NILP (color_val
) && max_key
> 0)
3965 if (xstrcasecmp (max_color
, "None") == 0)
3967 else if (x_defined_color (f
, max_color
, &cdef
, 0))
3968 color_val
= make_number (cdef
.pixel
);
3970 if (!NILP (color_val
))
3971 (*put_color_table
) (color_table
, beg
, chars_per_pixel
, color_val
);
3976 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
3977 &ximg
, &img
->pixmap
)
3979 || !x_create_x_image_and_pixmap (f
, width
, height
, 1,
3980 &mask_img
, &img
->mask
)
3984 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
3988 for (y
= 0; y
< height
; y
++)
3990 expect (XPM_TK_STRING
);
3992 if (len
< width
* chars_per_pixel
)
3994 for (x
= 0; x
< width
; x
++, str
+= chars_per_pixel
)
3996 Lisp_Object color_val
=
3997 (*get_color_table
) (color_table
, str
, chars_per_pixel
);
3999 XPutPixel (ximg
, x
, y
,
4000 (INTEGERP (color_val
) ? XINT (color_val
)
4001 : FRAME_FOREGROUND_PIXEL (f
)));
4003 XPutPixel (mask_img
, x
, y
,
4004 (!EQ (color_val
, Qt
) ? PIX_MASK_DRAW
4005 : (have_mask
= 1, PIX_MASK_RETAIN
)));
4007 if (EQ (color_val
, Qt
))
4008 ns_set_alpha (ximg
, x
, y
, 0);
4016 img
->height
= height
;
4018 /* Maybe fill in the background field while we have ximg handy. */
4019 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
4020 IMAGE_BACKGROUND (img
, f
, ximg
);
4022 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
4023 x_destroy_x_image (ximg
);
4027 /* Fill in the background_transparent field while we have the
4029 image_background_transparent (img
, f
, mask_img
);
4031 x_put_x_image (f
, mask_img
, img
->mask
, width
, height
);
4032 x_destroy_x_image (mask_img
);
4036 x_destroy_x_image (mask_img
);
4037 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4038 img
->mask
= NO_PIXMAP
;
4044 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
4046 x_destroy_x_image (ximg
);
4047 x_destroy_x_image (mask_img
);
4048 x_clear_image (f
, img
);
4062 Lisp_Object file_name
;
4064 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4065 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
4066 if (STRINGP (file_name
))
4069 unsigned char *contents
;
4071 struct gcpro gcpro1
;
4073 file
= x_find_image_file (file_name
);
4075 if (!STRINGP (file
))
4077 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
4082 contents
= slurp_file (SDATA (file
), &size
);
4083 if (contents
== NULL
)
4085 image_error ("Error loading XPM image `%s'", img
->spec
, Qnil
);
4090 success_p
= xpm_load_image (f
, img
, contents
, contents
+ size
);
4098 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
4099 success_p
= xpm_load_image (f
, img
, SDATA (data
),
4100 SDATA (data
) + SBYTES (data
));
4106 #endif /* HAVE_NS && !HAVE_XPM */
4110 /***********************************************************************
4112 ***********************************************************************/
4114 #ifdef COLOR_TABLE_SUPPORT
4116 /* An entry in the color table mapping an RGB color to a pixel color. */
4121 unsigned long pixel
;
4123 /* Next in color table collision list. */
4124 struct ct_color
*next
;
4127 /* The bucket vector size to use. Must be prime. */
4131 /* Value is a hash of the RGB color given by R, G, and B. */
4133 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
4135 /* The color hash table. */
4137 struct ct_color
**ct_table
;
4139 /* Number of entries in the color table. */
4141 int ct_colors_allocated
;
4143 /* Initialize the color table. */
4146 init_color_table (void)
4148 int size
= CT_SIZE
* sizeof (*ct_table
);
4149 ct_table
= (struct ct_color
**) xmalloc (size
);
4150 memset (ct_table
, 0, size
);
4151 ct_colors_allocated
= 0;
4155 /* Free memory associated with the color table. */
4158 free_color_table (void)
4161 struct ct_color
*p
, *next
;
4163 for (i
= 0; i
< CT_SIZE
; ++i
)
4164 for (p
= ct_table
[i
]; p
; p
= next
)
4175 /* Value is a pixel color for RGB color R, G, B on frame F. If an
4176 entry for that color already is in the color table, return the
4177 pixel color of that entry. Otherwise, allocate a new color for R,
4178 G, B, and make an entry in the color table. */
4180 static unsigned long
4181 lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
)
4183 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
4184 int i
= hash
% CT_SIZE
;
4186 Display_Info
*dpyinfo
;
4188 /* Handle TrueColor visuals specially, which improves performance by
4189 two orders of magnitude. Freeing colors on TrueColor visuals is
4190 a nop, and pixel colors specify RGB values directly. See also
4191 the Xlib spec, chapter 3.1. */
4192 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
4193 if (dpyinfo
->red_bits
> 0)
4195 unsigned long pr
, pg
, pb
;
4197 /* Apply gamma-correction like normal color allocation does. */
4201 color
.red
= r
, color
.green
= g
, color
.blue
= b
;
4202 gamma_correct (f
, &color
);
4203 r
= color
.red
, g
= color
.green
, b
= color
.blue
;
4206 /* Scale down RGB values to the visual's bits per RGB, and shift
4207 them to the right position in the pixel color. Note that the
4208 original RGB values are 16-bit values, as usual in X. */
4209 pr
= (r
>> (16 - dpyinfo
->red_bits
)) << dpyinfo
->red_offset
;
4210 pg
= (g
>> (16 - dpyinfo
->green_bits
)) << dpyinfo
->green_offset
;
4211 pb
= (b
>> (16 - dpyinfo
->blue_bits
)) << dpyinfo
->blue_offset
;
4213 /* Assemble the pixel color. */
4214 return pr
| pg
| pb
;
4217 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4218 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
4224 #ifdef HAVE_X_WINDOWS
4233 cmap
= FRAME_X_COLORMAP (f
);
4234 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4237 ++ct_colors_allocated
;
4238 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4242 p
->pixel
= color
.pixel
;
4243 p
->next
= ct_table
[i
];
4247 return FRAME_FOREGROUND_PIXEL (f
);
4252 color
= PALETTERGB (r
, g
, b
);
4254 color
= RGB_TO_ULONG (r
, g
, b
);
4255 #endif /* HAVE_NTGUI */
4256 ++ct_colors_allocated
;
4257 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4262 p
->next
= ct_table
[i
];
4264 #endif /* HAVE_X_WINDOWS */
4272 /* Look up pixel color PIXEL which is used on frame F in the color
4273 table. If not already present, allocate it. Value is PIXEL. */
4275 static unsigned long
4276 lookup_pixel_color (struct frame
*f
, unsigned long pixel
)
4278 int i
= pixel
% CT_SIZE
;
4281 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4282 if (p
->pixel
== pixel
)
4291 #ifdef HAVE_X_WINDOWS
4292 cmap
= FRAME_X_COLORMAP (f
);
4293 color
.pixel
= pixel
;
4294 x_query_color (f
, &color
);
4295 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4298 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
4299 color
.pixel
= pixel
;
4300 XQueryColor (NULL
, cmap
, &color
);
4301 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4303 #endif /* HAVE_X_WINDOWS */
4307 ++ct_colors_allocated
;
4309 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4314 p
->next
= ct_table
[i
];
4318 return FRAME_FOREGROUND_PIXEL (f
);
4324 /* Value is a vector of all pixel colors contained in the color table,
4325 allocated via xmalloc. Set *N to the number of colors. */
4327 static unsigned long *
4328 colors_in_color_table (int *n
)
4332 unsigned long *colors
;
4334 if (ct_colors_allocated
== 0)
4341 colors
= (unsigned long *) xmalloc (ct_colors_allocated
4343 *n
= ct_colors_allocated
;
4345 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
4346 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4347 colors
[j
++] = p
->pixel
;
4353 #else /* COLOR_TABLE_SUPPORT */
4355 static unsigned long
4356 lookup_rgb_color (f
, r
, g
, b
)
4360 unsigned long pixel
;
4363 pixel
= PALETTERGB (r
>> 8, g
>> 8, b
>> 8);
4364 #endif /* HAVE_NTGUI */
4367 pixel
= RGB_TO_ULONG (r
>> 8, g
>> 8, b
>> 8);
4368 #endif /* HAVE_NS */
4376 #endif /* COLOR_TABLE_SUPPORT */
4379 /***********************************************************************
4381 ***********************************************************************/
4383 static XColor
*x_to_xcolors (struct frame
*, struct image
*, int);
4384 static void x_from_xcolors (struct frame
*, struct image
*, XColor
*);
4385 static void x_detect_edges (struct frame
*, struct image
*, int[9], int);
4388 static void XPutPixel (XImagePtr
, int, int, COLORREF
);
4389 #endif /* HAVE_NTGUI */
4391 /* Non-zero means draw a cross on images having `:conversion
4394 int cross_disabled_images
;
4396 /* Edge detection matrices for different edge-detection
4399 static int emboss_matrix
[9] = {
4401 2, -1, 0, /* y - 1 */
4403 0, 1, -2 /* y + 1 */
4406 static int laplace_matrix
[9] = {
4408 1, 0, 0, /* y - 1 */
4410 0, 0, -1 /* y + 1 */
4413 /* Value is the intensity of the color whose red/green/blue values
4416 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
4419 /* On frame F, return an array of XColor structures describing image
4420 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
4421 non-zero means also fill the red/green/blue members of the XColor
4422 structures. Value is a pointer to the array of XColors structures,
4423 allocated with xmalloc; it must be freed by the caller. */
4426 x_to_xcolors (struct frame
*f
, struct image
*img
, int rgb_p
)
4430 XImagePtr_or_DC ximg
;
4434 #endif /* HAVE_NTGUI */
4436 colors
= (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *colors
);
4439 /* Get the X image IMG->pixmap. */
4440 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
4441 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4443 /* Load the image into a memory device context. */
4444 hdc
= get_frame_dc (f
);
4445 ximg
= CreateCompatibleDC (hdc
);
4446 release_frame_dc (f
, hdc
);
4447 prev
= SelectObject (ximg
, img
->pixmap
);
4448 #endif /* HAVE_NTGUI */
4450 /* Fill the `pixel' members of the XColor array. I wished there
4451 were an easy and portable way to circumvent XGetPixel. */
4453 for (y
= 0; y
< img
->height
; ++y
)
4457 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
4458 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4459 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4461 x_query_colors (f
, row
, img
->width
);
4465 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4467 /* W32_TODO: palette support needed here? */
4468 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4471 p
->red
= RED16_FROM_ULONG (p
->pixel
);
4472 p
->green
= GREEN16_FROM_ULONG (p
->pixel
);
4473 p
->blue
= BLUE16_FROM_ULONG (p
->pixel
);
4476 #endif /* HAVE_X_WINDOWS */
4479 Destroy_Image (ximg
, prev
);
4486 /* Put a pixel of COLOR at position X, Y in XIMG. XIMG must have been
4487 created with CreateDIBSection, with the pointer to the bit values
4488 stored in ximg->data. */
4491 XPutPixel (ximg
, x
, y
, color
)
4496 int width
= ximg
->info
.bmiHeader
.biWidth
;
4497 int height
= ximg
->info
.bmiHeader
.biHeight
;
4498 unsigned char * pixel
;
4500 /* True color images. */
4501 if (ximg
->info
.bmiHeader
.biBitCount
== 24)
4503 int rowbytes
= width
* 3;
4504 /* Ensure scanlines are aligned on 4 byte boundaries. */
4506 rowbytes
+= 4 - (rowbytes
% 4);
4508 pixel
= ximg
->data
+ y
* rowbytes
+ x
* 3;
4509 /* Windows bitmaps are in BGR order. */
4510 *pixel
= GetBValue (color
);
4511 *(pixel
+ 1) = GetGValue (color
);
4512 *(pixel
+ 2) = GetRValue (color
);
4514 /* Monochrome images. */
4515 else if (ximg
->info
.bmiHeader
.biBitCount
== 1)
4517 int rowbytes
= width
/ 8;
4518 /* Ensure scanlines are aligned on 4 byte boundaries. */
4520 rowbytes
+= 4 - (rowbytes
% 4);
4521 pixel
= ximg
->data
+ y
* rowbytes
+ x
/ 8;
4522 /* Filter out palette info. */
4523 if (color
& 0x00ffffff)
4524 *pixel
= *pixel
| (1 << x
% 8);
4526 *pixel
= *pixel
& ~(1 << x
% 8);
4529 image_error ("XPutPixel: palette image not supported", Qnil
, Qnil
);
4532 #endif /* HAVE_NTGUI */
4534 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
4535 RGB members are set. F is the frame on which this all happens.
4536 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
4539 x_from_xcolors (struct frame
*f
, struct image
*img
, XColor
*colors
)
4542 XImagePtr oimg
= NULL
;
4546 init_color_table ();
4548 x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
4551 for (y
= 0; y
< img
->height
; ++y
)
4552 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4554 unsigned long pixel
;
4555 pixel
= lookup_rgb_color (f
, p
->red
, p
->green
, p
->blue
);
4556 XPutPixel (oimg
, x
, y
, pixel
);
4560 x_clear_image_1 (f
, img
, 1, 0, 1);
4562 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
4563 x_destroy_x_image (oimg
);
4564 img
->pixmap
= pixmap
;
4565 #ifdef COLOR_TABLE_SUPPORT
4566 img
->colors
= colors_in_color_table (&img
->ncolors
);
4567 free_color_table ();
4568 #endif /* COLOR_TABLE_SUPPORT */
4572 /* On frame F, perform edge-detection on image IMG.
4574 MATRIX is a nine-element array specifying the transformation
4575 matrix. See emboss_matrix for an example.
4577 COLOR_ADJUST is a color adjustment added to each pixel of the
4581 x_detect_edges (struct frame
*f
, struct image
*img
, int *matrix
, int color_adjust
)
4583 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4587 for (i
= sum
= 0; i
< 9; ++i
)
4588 sum
+= eabs (matrix
[i
]);
4590 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
4592 new = (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *new);
4594 for (y
= 0; y
< img
->height
; ++y
)
4596 p
= COLOR (new, 0, y
);
4597 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4598 p
= COLOR (new, img
->width
- 1, y
);
4599 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4602 for (x
= 1; x
< img
->width
- 1; ++x
)
4604 p
= COLOR (new, x
, 0);
4605 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4606 p
= COLOR (new, x
, img
->height
- 1);
4607 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4610 for (y
= 1; y
< img
->height
- 1; ++y
)
4612 p
= COLOR (new, 1, y
);
4614 for (x
= 1; x
< img
->width
- 1; ++x
, ++p
)
4616 int r
, g
, b
, y1
, x1
;
4619 for (y1
= y
- 1; y1
< y
+ 2; ++y1
)
4620 for (x1
= x
- 1; x1
< x
+ 2; ++x1
, ++i
)
4623 XColor
*t
= COLOR (colors
, x1
, y1
);
4624 r
+= matrix
[i
] * t
->red
;
4625 g
+= matrix
[i
] * t
->green
;
4626 b
+= matrix
[i
] * t
->blue
;
4629 r
= (r
/ sum
+ color_adjust
) & 0xffff;
4630 g
= (g
/ sum
+ color_adjust
) & 0xffff;
4631 b
= (b
/ sum
+ color_adjust
) & 0xffff;
4632 p
->red
= p
->green
= p
->blue
= COLOR_INTENSITY (r
, g
, b
);
4637 x_from_xcolors (f
, img
, new);
4643 /* Perform the pre-defined `emboss' edge-detection on image IMG
4647 x_emboss (struct frame
*f
, struct image
*img
)
4649 x_detect_edges (f
, img
, emboss_matrix
, 0xffff / 2);
4653 /* Transform image IMG which is used on frame F with a Laplace
4654 edge-detection algorithm. The result is an image that can be used
4655 to draw disabled buttons, for example. */
4658 x_laplace (struct frame
*f
, struct image
*img
)
4660 x_detect_edges (f
, img
, laplace_matrix
, 45000);
4664 /* Perform edge-detection on image IMG on frame F, with specified
4665 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
4667 MATRIX must be either
4669 - a list of at least 9 numbers in row-major form
4670 - a vector of at least 9 numbers
4672 COLOR_ADJUST nil means use a default; otherwise it must be a
4676 x_edge_detection (struct frame
*f
, struct image
*img
, Lisp_Object matrix
,
4677 Lisp_Object color_adjust
)
4685 i
< 9 && CONSP (matrix
) && NUMBERP (XCAR (matrix
));
4686 ++i
, matrix
= XCDR (matrix
))
4687 trans
[i
] = XFLOATINT (XCAR (matrix
));
4689 else if (VECTORP (matrix
) && ASIZE (matrix
) >= 9)
4691 for (i
= 0; i
< 9 && NUMBERP (AREF (matrix
, i
)); ++i
)
4692 trans
[i
] = XFLOATINT (AREF (matrix
, i
));
4695 if (NILP (color_adjust
))
4696 color_adjust
= make_number (0xffff / 2);
4698 if (i
== 9 && NUMBERP (color_adjust
))
4699 x_detect_edges (f
, img
, trans
, (int) XFLOATINT (color_adjust
));
4703 /* Transform image IMG on frame F so that it looks disabled. */
4706 x_disable_image (struct frame
*f
, struct image
*img
)
4708 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
4710 int n_planes
= dpyinfo
->n_planes
* dpyinfo
->n_cbits
;
4712 int n_planes
= dpyinfo
->n_planes
;
4713 #endif /* HAVE_NTGUI */
4717 /* Color (or grayscale). Convert to gray, and equalize. Just
4718 drawing such images with a stipple can look very odd, so
4719 we're using this method instead. */
4720 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4722 const int h
= 15000;
4723 const int l
= 30000;
4725 for (p
= colors
, end
= colors
+ img
->width
* img
->height
;
4729 int i
= COLOR_INTENSITY (p
->red
, p
->green
, p
->blue
);
4730 int i2
= (0xffff - h
- l
) * i
/ 0xffff + l
;
4731 p
->red
= p
->green
= p
->blue
= i2
;
4734 x_from_xcolors (f
, img
, colors
);
4737 /* Draw a cross over the disabled image, if we must or if we
4739 if (n_planes
< 2 || cross_disabled_images
)
4742 Display
*dpy
= FRAME_X_DISPLAY (f
);
4745 #ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
4747 #define MaskForeground(f) WHITE_PIX_DEFAULT (f)
4749 gc
= XCreateGC (dpy
, img
->pixmap
, 0, NULL
);
4750 XSetForeground (dpy
, gc
, BLACK_PIX_DEFAULT (f
));
4751 XDrawLine (dpy
, img
->pixmap
, gc
, 0, 0,
4752 img
->width
- 1, img
->height
- 1);
4753 XDrawLine (dpy
, img
->pixmap
, gc
, 0, img
->height
- 1,
4759 gc
= XCreateGC (dpy
, img
->mask
, 0, NULL
);
4760 XSetForeground (dpy
, gc
, MaskForeground (f
));
4761 XDrawLine (dpy
, img
->mask
, gc
, 0, 0,
4762 img
->width
- 1, img
->height
- 1);
4763 XDrawLine (dpy
, img
->mask
, gc
, 0, img
->height
- 1,
4767 #endif /* !HAVE_NS */
4772 hdc
= get_frame_dc (f
);
4773 bmpdc
= CreateCompatibleDC (hdc
);
4774 release_frame_dc (f
, hdc
);
4776 prev
= SelectObject (bmpdc
, img
->pixmap
);
4778 SetTextColor (bmpdc
, BLACK_PIX_DEFAULT (f
));
4779 MoveToEx (bmpdc
, 0, 0, NULL
);
4780 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
4781 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
4782 LineTo (bmpdc
, img
->width
- 1, 0);
4786 SelectObject (bmpdc
, img
->mask
);
4787 SetTextColor (bmpdc
, WHITE_PIX_DEFAULT (f
));
4788 MoveToEx (bmpdc
, 0, 0, NULL
);
4789 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
4790 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
4791 LineTo (bmpdc
, img
->width
- 1, 0);
4793 SelectObject (bmpdc
, prev
);
4795 #endif /* HAVE_NTGUI */
4800 /* Build a mask for image IMG which is used on frame F. FILE is the
4801 name of an image file, for error messages. HOW determines how to
4802 determine the background color of IMG. If it is a list '(R G B)',
4803 with R, G, and B being integers >= 0, take that as the color of the
4804 background. Otherwise, determine the background color of IMG
4805 heuristically. Value is non-zero if successful. */
4808 x_build_heuristic_mask (struct frame
*f
, struct image
*img
, Lisp_Object how
)
4810 XImagePtr_or_DC ximg
;
4818 #endif /* HAVE_NTGUI */
4819 int x
, y
, rc
, use_img_background
;
4820 unsigned long bg
= 0;
4824 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4825 img
->mask
= NO_PIXMAP
;
4826 img
->background_transparent_valid
= 0;
4831 /* Create an image and pixmap serving as mask. */
4832 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
4833 &mask_img
, &img
->mask
);
4836 #endif /* !HAVE_NS */
4838 /* Get the X image of IMG->pixmap. */
4839 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
, 0, 0,
4840 img
->width
, img
->height
,
4843 /* Create the bit array serving as mask. */
4844 row_width
= (img
->width
+ 7) / 8;
4845 mask_img
= xmalloc (row_width
* img
->height
);
4846 memset (mask_img
, 0, row_width
* img
->height
);
4848 /* Create a memory device context for IMG->pixmap. */
4849 frame_dc
= get_frame_dc (f
);
4850 ximg
= CreateCompatibleDC (frame_dc
);
4851 release_frame_dc (f
, frame_dc
);
4852 prev
= SelectObject (ximg
, img
->pixmap
);
4853 #endif /* HAVE_NTGUI */
4855 /* Determine the background color of ximg. If HOW is `(R G B)'
4856 take that as color. Otherwise, use the image's background color. */
4857 use_img_background
= 1;
4863 for (i
= 0; i
< 3 && CONSP (how
) && NATNUMP (XCAR (how
)); ++i
)
4865 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
4869 if (i
== 3 && NILP (how
))
4871 char color_name
[30];
4872 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
4875 0x00ffffff & /* Filter out palette info. */
4876 #endif /* HAVE_NTGUI */
4877 x_alloc_image_color (f
, img
, build_string (color_name
), 0));
4878 use_img_background
= 0;
4882 if (use_img_background
)
4883 bg
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
4885 /* Set all bits in mask_img to 1 whose color in ximg is different
4886 from the background color bg. */
4888 for (y
= 0; y
< img
->height
; ++y
)
4889 for (x
= 0; x
< img
->width
; ++x
)
4891 XPutPixel (mask_img
, x
, y
, (XGetPixel (ximg
, x
, y
) != bg
4892 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
));
4894 if (XGetPixel (ximg
, x
, y
) == bg
)
4895 ns_set_alpha (ximg
, x
, y
, 0);
4896 #endif /* HAVE_NS */
4898 /* Fill in the background_transparent field while we have the mask handy. */
4899 image_background_transparent (img
, f
, mask_img
);
4901 /* Put mask_img into img->mask. */
4902 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
4903 x_destroy_x_image (mask_img
);
4904 #endif /* !HAVE_NS */
4906 for (y
= 0; y
< img
->height
; ++y
)
4907 for (x
= 0; x
< img
->width
; ++x
)
4909 COLORREF p
= GetPixel (ximg
, x
, y
);
4911 mask_img
[y
* row_width
+ x
/ 8] |= 1 << (x
% 8);
4914 /* Create the mask image. */
4915 img
->mask
= w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
,
4917 /* Fill in the background_transparent field while we have the mask handy. */
4918 SelectObject (ximg
, img
->mask
);
4919 image_background_transparent (img
, f
, ximg
);
4921 /* Was: x_destroy_x_image ((XImagePtr )mask_img); which seems bogus ++kfs */
4923 #endif /* HAVE_NTGUI */
4925 Destroy_Image (ximg
, prev
);
4931 /***********************************************************************
4932 PBM (mono, gray, color)
4933 ***********************************************************************/
4935 static int pbm_image_p (Lisp_Object object
);
4936 static int pbm_load (struct frame
*f
, struct image
*img
);
4937 static int pbm_scan_number (unsigned char **, unsigned char *);
4939 /* The symbol `pbm' identifying images of this type. */
4943 /* Indices of image specification fields in gs_format, below. */
4945 enum pbm_keyword_index
4961 /* Vector of image_keyword structures describing the format
4962 of valid user-defined image specifications. */
4964 static const struct image_keyword pbm_format
[PBM_LAST
] =
4966 {":type", IMAGE_SYMBOL_VALUE
, 1},
4967 {":file", IMAGE_STRING_VALUE
, 0},
4968 {":data", IMAGE_STRING_VALUE
, 0},
4969 {":ascent", IMAGE_ASCENT_VALUE
, 0},
4970 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
4971 {":relief", IMAGE_INTEGER_VALUE
, 0},
4972 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4973 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4974 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4975 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
4976 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
4979 /* Structure describing the image type `pbm'. */
4981 static struct image_type pbm_type
=
4991 /* Return non-zero if OBJECT is a valid PBM image specification. */
4994 pbm_image_p (Lisp_Object object
)
4996 struct image_keyword fmt
[PBM_LAST
];
4998 memcpy (fmt
, pbm_format
, sizeof fmt
);
5000 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
))
5003 /* Must specify either :data or :file. */
5004 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
5008 /* Scan a decimal number from *S and return it. Advance *S while
5009 reading the number. END is the end of the string. Value is -1 at
5013 pbm_scan_number (unsigned char **s
, unsigned char *end
)
5015 int c
= 0, val
= -1;
5019 /* Skip white-space. */
5020 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
5025 /* Skip comment to end of line. */
5026 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
5029 else if (isdigit (c
))
5031 /* Read decimal number. */
5033 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
5034 val
= 10 * val
+ c
- '0';
5046 #if 0 /* Unused. ++kfs */
5048 /* Read FILE into memory. Value is a pointer to a buffer allocated
5049 with xmalloc holding FILE's contents. Value is null if an error
5050 occurred. *SIZE is set to the size of the file. */
5053 pbm_read_file (file
, size
)
5061 if (stat (SDATA (file
), &st
) == 0
5062 && (fp
= fopen (SDATA (file
), "rb")) != NULL
5063 && (buf
= (char *) xmalloc (st
.st_size
),
5064 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
5083 #endif /* HAVE_NTGUI */
5085 /* Load PBM image IMG for use on frame F. */
5088 pbm_load (struct frame
*f
, struct image
*img
)
5091 int width
, height
, max_color_idx
= 0;
5093 Lisp_Object file
, specified_file
;
5094 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
5095 struct gcpro gcpro1
;
5096 unsigned char *contents
= NULL
;
5097 unsigned char *end
, *p
;
5100 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5104 if (STRINGP (specified_file
))
5106 file
= x_find_image_file (specified_file
);
5107 if (!STRINGP (file
))
5109 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5114 contents
= slurp_file (SDATA (file
), &size
);
5115 if (contents
== NULL
)
5117 image_error ("Error reading `%s'", file
, Qnil
);
5123 end
= contents
+ size
;
5128 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5130 end
= p
+ SBYTES (data
);
5133 /* Check magic number. */
5134 if (end
- p
< 2 || *p
++ != 'P')
5136 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5146 raw_p
= 0, type
= PBM_MONO
;
5150 raw_p
= 0, type
= PBM_GRAY
;
5154 raw_p
= 0, type
= PBM_COLOR
;
5158 raw_p
= 1, type
= PBM_MONO
;
5162 raw_p
= 1, type
= PBM_GRAY
;
5166 raw_p
= 1, type
= PBM_COLOR
;
5170 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5174 /* Read width, height, maximum color-component. Characters
5175 starting with `#' up to the end of a line are ignored. */
5176 width
= pbm_scan_number (&p
, end
);
5177 height
= pbm_scan_number (&p
, end
);
5179 if (type
!= PBM_MONO
)
5181 max_color_idx
= pbm_scan_number (&p
, end
);
5182 if (max_color_idx
> 65535 || max_color_idx
< 0)
5184 image_error ("Unsupported maximum PBM color value", Qnil
, Qnil
);
5189 if (!check_image_size (f
, width
, height
))
5191 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
5195 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
5196 &ximg
, &img
->pixmap
))
5199 /* Initialize the color hash table. */
5200 init_color_table ();
5202 if (type
== PBM_MONO
)
5205 struct image_keyword fmt
[PBM_LAST
];
5206 unsigned long fg
= FRAME_FOREGROUND_PIXEL (f
);
5207 unsigned long bg
= FRAME_BACKGROUND_PIXEL (f
);
5209 /* Parse the image specification. */
5210 memcpy (fmt
, pbm_format
, sizeof fmt
);
5211 parse_image_spec (img
->spec
, fmt
, PBM_LAST
, Qpbm
);
5213 /* Get foreground and background colors, maybe allocate colors. */
5214 if (fmt
[PBM_FOREGROUND
].count
5215 && STRINGP (fmt
[PBM_FOREGROUND
].value
))
5216 fg
= x_alloc_image_color (f
, img
, fmt
[PBM_FOREGROUND
].value
, fg
);
5217 if (fmt
[PBM_BACKGROUND
].count
5218 && STRINGP (fmt
[PBM_BACKGROUND
].value
))
5220 bg
= x_alloc_image_color (f
, img
, fmt
[PBM_BACKGROUND
].value
, bg
);
5221 img
->background
= bg
;
5222 img
->background_valid
= 1;
5225 for (y
= 0; y
< height
; ++y
)
5226 for (x
= 0; x
< width
; ++x
)
5234 x_destroy_x_image (ximg
);
5235 x_clear_image (f
, img
);
5236 image_error ("Invalid image size in image `%s'",
5246 g
= pbm_scan_number (&p
, end
);
5248 XPutPixel (ximg
, x
, y
, g
? fg
: bg
);
5253 int expected_size
= height
* width
;
5254 if (max_color_idx
> 255)
5256 if (type
== PBM_COLOR
)
5259 if (raw_p
&& p
+ expected_size
> end
)
5261 x_destroy_x_image (ximg
);
5262 x_clear_image (f
, img
);
5263 image_error ("Invalid image size in image `%s'",
5268 for (y
= 0; y
< height
; ++y
)
5269 for (x
= 0; x
< width
; ++x
)
5273 if (type
== PBM_GRAY
&& raw_p
)
5276 if (max_color_idx
> 255)
5277 r
= g
= b
= r
* 256 + *p
++;
5279 else if (type
== PBM_GRAY
)
5280 r
= g
= b
= pbm_scan_number (&p
, end
);
5284 if (max_color_idx
> 255)
5287 if (max_color_idx
> 255)
5290 if (max_color_idx
> 255)
5295 r
= pbm_scan_number (&p
, end
);
5296 g
= pbm_scan_number (&p
, end
);
5297 b
= pbm_scan_number (&p
, end
);
5300 if (r
< 0 || g
< 0 || b
< 0)
5302 x_destroy_x_image (ximg
);
5303 image_error ("Invalid pixel value in image `%s'",
5308 /* RGB values are now in the range 0..max_color_idx.
5309 Scale this to the range 0..0xffff supported by X. */
5310 r
= (double) r
* 65535 / max_color_idx
;
5311 g
= (double) g
* 65535 / max_color_idx
;
5312 b
= (double) b
* 65535 / max_color_idx
;
5313 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
5317 #ifdef COLOR_TABLE_SUPPORT
5318 /* Store in IMG->colors the colors allocated for the image, and
5319 free the color table. */
5320 img
->colors
= colors_in_color_table (&img
->ncolors
);
5321 free_color_table ();
5322 #endif /* COLOR_TABLE_SUPPORT */
5325 img
->height
= height
;
5327 /* Maybe fill in the background field while we have ximg handy. */
5329 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
5330 /* Casting avoids a GCC warning. */
5331 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
5333 /* Put the image into a pixmap. */
5334 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
5335 x_destroy_x_image (ximg
);
5337 /* X and W32 versions did it here, MAC version above. ++kfs
5339 img->height = height; */
5347 /***********************************************************************
5349 ***********************************************************************/
5351 #if defined (HAVE_PNG) || defined (HAVE_NS)
5353 /* Function prototypes. */
5355 static int png_image_p (Lisp_Object object
);
5356 static int png_load (struct frame
*f
, struct image
*img
);
5358 /* The symbol `png' identifying images of this type. */
5362 /* Indices of image specification fields in png_format, below. */
5364 enum png_keyword_index
5379 /* Vector of image_keyword structures describing the format
5380 of valid user-defined image specifications. */
5382 static const struct image_keyword png_format
[PNG_LAST
] =
5384 {":type", IMAGE_SYMBOL_VALUE
, 1},
5385 {":data", IMAGE_STRING_VALUE
, 0},
5386 {":file", IMAGE_STRING_VALUE
, 0},
5387 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5388 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5389 {":relief", IMAGE_INTEGER_VALUE
, 0},
5390 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5391 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5392 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5393 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
5396 /* Structure describing the image type `png'. */
5398 static struct image_type png_type
=
5407 /* Return non-zero if OBJECT is a valid PNG image specification. */
5410 png_image_p (Lisp_Object object
)
5412 struct image_keyword fmt
[PNG_LAST
];
5413 memcpy (fmt
, png_format
, sizeof fmt
);
5415 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
5418 /* Must specify either the :data or :file keyword. */
5419 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
5422 #endif /* HAVE_PNG || HAVE_NS */
5428 /* PNG library details. */
5430 DEF_IMGLIB_FN (png_get_io_ptr
);
5431 DEF_IMGLIB_FN (png_sig_cmp
);
5432 DEF_IMGLIB_FN (png_create_read_struct
);
5433 DEF_IMGLIB_FN (png_create_info_struct
);
5434 DEF_IMGLIB_FN (png_destroy_read_struct
);
5435 DEF_IMGLIB_FN (png_set_read_fn
);
5436 DEF_IMGLIB_FN (png_set_sig_bytes
);
5437 DEF_IMGLIB_FN (png_read_info
);
5438 DEF_IMGLIB_FN (png_get_IHDR
);
5439 DEF_IMGLIB_FN (png_get_valid
);
5440 DEF_IMGLIB_FN (png_set_strip_16
);
5441 DEF_IMGLIB_FN (png_set_expand
);
5442 DEF_IMGLIB_FN (png_set_gray_to_rgb
);
5443 DEF_IMGLIB_FN (png_set_background
);
5444 DEF_IMGLIB_FN (png_get_bKGD
);
5445 DEF_IMGLIB_FN (png_read_update_info
);
5446 DEF_IMGLIB_FN (png_get_channels
);
5447 DEF_IMGLIB_FN (png_get_rowbytes
);
5448 DEF_IMGLIB_FN (png_read_image
);
5449 DEF_IMGLIB_FN (png_read_end
);
5450 DEF_IMGLIB_FN (png_error
);
5453 init_png_functions (Lisp_Object libraries
)
5457 /* Try loading libpng under probable names. */
5458 if (!(library
= w32_delayed_load (libraries
, Qpng
)))
5461 LOAD_IMGLIB_FN (library
, png_get_io_ptr
);
5462 LOAD_IMGLIB_FN (library
, png_sig_cmp
);
5463 LOAD_IMGLIB_FN (library
, png_create_read_struct
);
5464 LOAD_IMGLIB_FN (library
, png_create_info_struct
);
5465 LOAD_IMGLIB_FN (library
, png_destroy_read_struct
);
5466 LOAD_IMGLIB_FN (library
, png_set_read_fn
);
5467 LOAD_IMGLIB_FN (library
, png_set_sig_bytes
);
5468 LOAD_IMGLIB_FN (library
, png_read_info
);
5469 LOAD_IMGLIB_FN (library
, png_get_IHDR
);
5470 LOAD_IMGLIB_FN (library
, png_get_valid
);
5471 LOAD_IMGLIB_FN (library
, png_set_strip_16
);
5472 LOAD_IMGLIB_FN (library
, png_set_expand
);
5473 LOAD_IMGLIB_FN (library
, png_set_gray_to_rgb
);
5474 LOAD_IMGLIB_FN (library
, png_set_background
);
5475 LOAD_IMGLIB_FN (library
, png_get_bKGD
);
5476 LOAD_IMGLIB_FN (library
, png_read_update_info
);
5477 LOAD_IMGLIB_FN (library
, png_get_channels
);
5478 LOAD_IMGLIB_FN (library
, png_get_rowbytes
);
5479 LOAD_IMGLIB_FN (library
, png_read_image
);
5480 LOAD_IMGLIB_FN (library
, png_read_end
);
5481 LOAD_IMGLIB_FN (library
, png_error
);
5486 #define fn_png_get_io_ptr png_get_io_ptr
5487 #define fn_png_sig_cmp png_sig_cmp
5488 #define fn_png_create_read_struct png_create_read_struct
5489 #define fn_png_create_info_struct png_create_info_struct
5490 #define fn_png_destroy_read_struct png_destroy_read_struct
5491 #define fn_png_set_read_fn png_set_read_fn
5492 #define fn_png_set_sig_bytes png_set_sig_bytes
5493 #define fn_png_read_info png_read_info
5494 #define fn_png_get_IHDR png_get_IHDR
5495 #define fn_png_get_valid png_get_valid
5496 #define fn_png_set_strip_16 png_set_strip_16
5497 #define fn_png_set_expand png_set_expand
5498 #define fn_png_set_gray_to_rgb png_set_gray_to_rgb
5499 #define fn_png_set_background png_set_background
5500 #define fn_png_get_bKGD png_get_bKGD
5501 #define fn_png_read_update_info png_read_update_info
5502 #define fn_png_get_channels png_get_channels
5503 #define fn_png_get_rowbytes png_get_rowbytes
5504 #define fn_png_read_image png_read_image
5505 #define fn_png_read_end png_read_end
5506 #define fn_png_error png_error
5508 #endif /* HAVE_NTGUI */
5510 /* Error and warning handlers installed when the PNG library
5514 my_png_error (png_struct
*png_ptr
, const char *msg
)
5516 xassert (png_ptr
!= NULL
);
5517 image_error ("PNG error: %s", build_string (msg
), Qnil
);
5518 longjmp (png_ptr
->jmpbuf
, 1);
5523 my_png_warning (png_struct
*png_ptr
, const char *msg
)
5525 xassert (png_ptr
!= NULL
);
5526 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
5529 /* Memory source for PNG decoding. */
5531 struct png_memory_storage
5533 unsigned char *bytes
; /* The data */
5534 size_t len
; /* How big is it? */
5535 int index
; /* Where are we? */
5539 /* Function set as reader function when reading PNG image from memory.
5540 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5541 bytes from the input to DATA. */
5544 png_read_from_memory (png_structp png_ptr
, png_bytep data
, png_size_t length
)
5546 struct png_memory_storage
*tbr
5547 = (struct png_memory_storage
*) fn_png_get_io_ptr (png_ptr
);
5549 if (length
> tbr
->len
- tbr
->index
)
5550 fn_png_error (png_ptr
, "Read error");
5552 memcpy (data
, tbr
->bytes
+ tbr
->index
, length
);
5553 tbr
->index
= tbr
->index
+ length
;
5557 /* Function set as reader function when reading PNG image from a file.
5558 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5559 bytes from the input to DATA. */
5562 png_read_from_file (png_structp png_ptr
, png_bytep data
, png_size_t length
)
5564 FILE *fp
= (FILE *) fn_png_get_io_ptr (png_ptr
);
5566 if (fread (data
, 1, length
, fp
) < length
)
5567 fn_png_error (png_ptr
, "Read error");
5571 /* Load PNG image IMG for use on frame F. Value is non-zero if
5575 png_load (struct frame
*f
, struct image
*img
)
5577 Lisp_Object file
, specified_file
;
5578 Lisp_Object specified_data
;
5580 XImagePtr ximg
, mask_img
= NULL
;
5581 struct gcpro gcpro1
;
5582 png_struct
*png_ptr
= NULL
;
5583 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
5584 FILE *volatile fp
= NULL
;
5586 png_byte
* volatile pixels
= NULL
;
5587 png_byte
** volatile rows
= NULL
;
5588 png_uint_32 width
, height
;
5589 int bit_depth
, color_type
, interlace_type
;
5591 png_uint_32 row_bytes
;
5593 struct png_memory_storage tbr
; /* Data to be read */
5595 /* Find out what file to load. */
5596 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5597 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5601 if (NILP (specified_data
))
5603 file
= x_find_image_file (specified_file
);
5604 if (!STRINGP (file
))
5606 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5611 /* Open the image file. */
5612 fp
= fopen (SDATA (file
), "rb");
5615 image_error ("Cannot open image file `%s'", file
, Qnil
);
5620 /* Check PNG signature. */
5621 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
5622 || fn_png_sig_cmp (sig
, 0, sizeof sig
))
5624 image_error ("Not a PNG file: `%s'", file
, Qnil
);
5632 /* Read from memory. */
5633 tbr
.bytes
= SDATA (specified_data
);
5634 tbr
.len
= SBYTES (specified_data
);
5637 /* Check PNG signature. */
5638 if (tbr
.len
< sizeof sig
5639 || fn_png_sig_cmp (tbr
.bytes
, 0, sizeof sig
))
5641 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
5646 /* Need to skip past the signature. */
5647 tbr
.bytes
+= sizeof (sig
);
5650 /* Initialize read and info structs for PNG lib. Casting return
5651 value avoids a GCC warning on W32. */
5652 png_ptr
= (png_structp
)fn_png_create_read_struct (PNG_LIBPNG_VER_STRING
,
5657 if (fp
) fclose (fp
);
5662 /* Casting return value avoids a GCC warning on W32. */
5663 info_ptr
= (png_infop
)fn_png_create_info_struct (png_ptr
);
5666 fn_png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
5667 if (fp
) fclose (fp
);
5672 /* Casting return value avoids a GCC warning on W32. */
5673 end_info
= (png_infop
)fn_png_create_info_struct (png_ptr
);
5676 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
5677 if (fp
) fclose (fp
);
5682 /* Set error jump-back. We come back here when the PNG library
5683 detects an error. */
5684 if (setjmp (png_ptr
->jmpbuf
))
5688 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
5691 if (fp
) fclose (fp
);
5696 /* Read image info. */
5697 if (!NILP (specified_data
))
5698 fn_png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
5700 fn_png_set_read_fn (png_ptr
, (void *) fp
, png_read_from_file
);
5702 fn_png_set_sig_bytes (png_ptr
, sizeof sig
);
5703 fn_png_read_info (png_ptr
, info_ptr
);
5704 fn_png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
5705 &interlace_type
, NULL
, NULL
);
5707 if (!check_image_size (f
, width
, height
))
5709 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
5712 /* If image contains simply transparency data, we prefer to
5713 construct a clipping mask. */
5714 if (fn_png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
5719 /* This function is easier to write if we only have to handle
5720 one data format: RGB or RGBA with 8 bits per channel. Let's
5721 transform other formats into that format. */
5723 /* Strip more than 8 bits per channel. */
5724 if (bit_depth
== 16)
5725 fn_png_set_strip_16 (png_ptr
);
5727 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
5729 fn_png_set_expand (png_ptr
);
5731 /* Convert grayscale images to RGB. */
5732 if (color_type
== PNG_COLOR_TYPE_GRAY
5733 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
5734 fn_png_set_gray_to_rgb (png_ptr
);
5736 /* Handle alpha channel by combining the image with a background
5737 color. Do this only if a real alpha channel is supplied. For
5738 simple transparency, we prefer a clipping mask. */
5741 /* png_color_16 *image_bg; */
5742 Lisp_Object specified_bg
5743 = image_spec_value (img
->spec
, QCbackground
, NULL
);
5744 int shift
= (bit_depth
== 16) ? 0 : 8;
5746 if (STRINGP (specified_bg
))
5747 /* The user specified `:background', use that. */
5750 if (x_defined_color (f
, SDATA (specified_bg
), &color
, 0))
5752 png_color_16 user_bg
;
5754 memset (&user_bg
, 0, sizeof user_bg
);
5755 user_bg
.red
= color
.red
>> shift
;
5756 user_bg
.green
= color
.green
>> shift
;
5757 user_bg
.blue
= color
.blue
>> shift
;
5759 fn_png_set_background (png_ptr
, &user_bg
,
5760 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
5765 /* We use the current frame background, ignoring any default
5766 background color set by the image. */
5767 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
5769 png_color_16 frame_background
;
5771 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
5772 x_query_color (f
, &color
);
5774 memset (&frame_background
, 0, sizeof frame_background
);
5775 frame_background
.red
= color
.red
>> shift
;
5776 frame_background
.green
= color
.green
>> shift
;
5777 frame_background
.blue
= color
.blue
>> shift
;
5778 #endif /* HAVE_X_WINDOWS */
5780 fn_png_set_background (png_ptr
, &frame_background
,
5781 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
5785 /* Update info structure. */
5786 fn_png_read_update_info (png_ptr
, info_ptr
);
5788 /* Get number of channels. Valid values are 1 for grayscale images
5789 and images with a palette, 2 for grayscale images with transparency
5790 information (alpha channel), 3 for RGB images, and 4 for RGB
5791 images with alpha channel, i.e. RGBA. If conversions above were
5792 sufficient we should only have 3 or 4 channels here. */
5793 channels
= fn_png_get_channels (png_ptr
, info_ptr
);
5794 xassert (channels
== 3 || channels
== 4);
5796 /* Number of bytes needed for one row of the image. */
5797 row_bytes
= fn_png_get_rowbytes (png_ptr
, info_ptr
);
5799 /* Allocate memory for the image. */
5800 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
5801 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
5802 for (i
= 0; i
< height
; ++i
)
5803 rows
[i
] = pixels
+ i
* row_bytes
;
5805 /* Read the entire image. */
5806 fn_png_read_image (png_ptr
, rows
);
5807 fn_png_read_end (png_ptr
, info_ptr
);
5814 /* Create the X image and pixmap. */
5815 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
5819 /* Create an image and pixmap serving as mask if the PNG image
5820 contains an alpha channel. */
5823 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
5824 &mask_img
, &img
->mask
))
5826 x_destroy_x_image (ximg
);
5827 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
5828 img
->pixmap
= NO_PIXMAP
;
5832 /* Fill the X image and mask from PNG data. */
5833 init_color_table ();
5835 for (y
= 0; y
< height
; ++y
)
5837 png_byte
*p
= rows
[y
];
5839 for (x
= 0; x
< width
; ++x
)
5846 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
5847 /* An alpha channel, aka mask channel, associates variable
5848 transparency with an image. Where other image formats
5849 support binary transparency---fully transparent or fully
5850 opaque---PNG allows up to 254 levels of partial transparency.
5851 The PNG library implements partial transparency by combining
5852 the image with a specified background color.
5854 I'm not sure how to handle this here nicely: because the
5855 background on which the image is displayed may change, for
5856 real alpha channel support, it would be necessary to create
5857 a new image for each possible background.
5859 What I'm doing now is that a mask is created if we have
5860 boolean transparency information. Otherwise I'm using
5861 the frame's background color to combine the image with. */
5866 XPutPixel (mask_img
, x
, y
, *p
> 0 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
);
5872 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
5873 /* Set IMG's background color from the PNG image, unless the user
5877 if (fn_png_get_bKGD (png_ptr
, info_ptr
, &bg
))
5879 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
5880 img
->background_valid
= 1;
5884 #ifdef COLOR_TABLE_SUPPORT
5885 /* Remember colors allocated for this image. */
5886 img
->colors
= colors_in_color_table (&img
->ncolors
);
5887 free_color_table ();
5888 #endif /* COLOR_TABLE_SUPPORT */
5891 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
5896 img
->height
= height
;
5898 /* Maybe fill in the background field while we have ximg handy.
5899 Casting avoids a GCC warning. */
5900 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
5902 /* Put the image into the pixmap, then free the X image and its buffer. */
5903 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
5904 x_destroy_x_image (ximg
);
5906 /* Same for the mask. */
5909 /* Fill in the background_transparent field while we have the
5910 mask handy. Casting avoids a GCC warning. */
5911 image_background_transparent (img
, f
, (XImagePtr_or_DC
)mask_img
);
5913 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
5914 x_destroy_x_image (mask_img
);
5921 #else /* HAVE_PNG */
5925 png_load (struct frame
*f
, struct image
*img
)
5927 return ns_load_image(f
, img
,
5928 image_spec_value (img
->spec
, QCfile
, NULL
),
5929 image_spec_value (img
->spec
, QCdata
, NULL
));
5931 #endif /* HAVE_NS */
5934 #endif /* !HAVE_PNG */
5938 /***********************************************************************
5940 ***********************************************************************/
5942 #if defined (HAVE_JPEG) || defined (HAVE_NS)
5944 static int jpeg_image_p (Lisp_Object object
);
5945 static int jpeg_load (struct frame
*f
, struct image
*img
);
5947 /* The symbol `jpeg' identifying images of this type. */
5951 /* Indices of image specification fields in gs_format, below. */
5953 enum jpeg_keyword_index
5962 JPEG_HEURISTIC_MASK
,
5968 /* Vector of image_keyword structures describing the format
5969 of valid user-defined image specifications. */
5971 static const struct image_keyword jpeg_format
[JPEG_LAST
] =
5973 {":type", IMAGE_SYMBOL_VALUE
, 1},
5974 {":data", IMAGE_STRING_VALUE
, 0},
5975 {":file", IMAGE_STRING_VALUE
, 0},
5976 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5977 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5978 {":relief", IMAGE_INTEGER_VALUE
, 0},
5979 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5980 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5981 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5982 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
5985 /* Structure describing the image type `jpeg'. */
5987 static struct image_type jpeg_type
=
5996 /* Return non-zero if OBJECT is a valid JPEG image specification. */
5999 jpeg_image_p (Lisp_Object object
)
6001 struct image_keyword fmt
[JPEG_LAST
];
6003 memcpy (fmt
, jpeg_format
, sizeof fmt
);
6005 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
6008 /* Must specify either the :data or :file keyword. */
6009 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
6012 #endif /* HAVE_JPEG || HAVE_NS */
6016 /* Work around a warning about HAVE_STDLIB_H being redefined in
6018 #ifdef HAVE_STDLIB_H
6019 #define HAVE_STDLIB_H_1
6020 #undef HAVE_STDLIB_H
6021 #endif /* HAVE_STLIB_H */
6023 #if defined (HAVE_NTGUI) && !defined (__WIN32__)
6024 /* In older releases of the jpeg library, jpeglib.h will define boolean
6025 differently depending on __WIN32__, so make sure it is defined. */
6029 #include <jpeglib.h>
6032 #ifdef HAVE_STLIB_H_1
6033 #define HAVE_STDLIB_H 1
6038 /* JPEG library details. */
6039 DEF_IMGLIB_FN (jpeg_CreateDecompress
);
6040 DEF_IMGLIB_FN (jpeg_start_decompress
);
6041 DEF_IMGLIB_FN (jpeg_finish_decompress
);
6042 DEF_IMGLIB_FN (jpeg_destroy_decompress
);
6043 DEF_IMGLIB_FN (jpeg_read_header
);
6044 DEF_IMGLIB_FN (jpeg_read_scanlines
);
6045 DEF_IMGLIB_FN (jpeg_std_error
);
6046 DEF_IMGLIB_FN (jpeg_resync_to_restart
);
6049 init_jpeg_functions (Lisp_Object libraries
)
6053 if (!(library
= w32_delayed_load (libraries
, Qjpeg
)))
6056 LOAD_IMGLIB_FN (library
, jpeg_finish_decompress
);
6057 LOAD_IMGLIB_FN (library
, jpeg_read_scanlines
);
6058 LOAD_IMGLIB_FN (library
, jpeg_start_decompress
);
6059 LOAD_IMGLIB_FN (library
, jpeg_read_header
);
6060 LOAD_IMGLIB_FN (library
, jpeg_CreateDecompress
);
6061 LOAD_IMGLIB_FN (library
, jpeg_destroy_decompress
);
6062 LOAD_IMGLIB_FN (library
, jpeg_std_error
);
6063 LOAD_IMGLIB_FN (library
, jpeg_resync_to_restart
);
6067 /* Wrapper since we can't directly assign the function pointer
6068 to another function pointer that was declared more completely easily. */
6070 jpeg_resync_to_restart_wrapper (cinfo
, desired
)
6071 j_decompress_ptr cinfo
;
6074 return fn_jpeg_resync_to_restart (cinfo
, desired
);
6079 #define fn_jpeg_CreateDecompress(a,b,c) jpeg_create_decompress(a)
6080 #define fn_jpeg_start_decompress jpeg_start_decompress
6081 #define fn_jpeg_finish_decompress jpeg_finish_decompress
6082 #define fn_jpeg_destroy_decompress jpeg_destroy_decompress
6083 #define fn_jpeg_read_header jpeg_read_header
6084 #define fn_jpeg_read_scanlines jpeg_read_scanlines
6085 #define fn_jpeg_std_error jpeg_std_error
6086 #define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart
6088 #endif /* HAVE_NTGUI */
6090 struct my_jpeg_error_mgr
6092 struct jpeg_error_mgr pub
;
6093 jmp_buf setjmp_buffer
;
6098 my_error_exit (j_common_ptr cinfo
)
6100 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
6101 longjmp (mgr
->setjmp_buffer
, 1);
6105 /* Init source method for JPEG data source manager. Called by
6106 jpeg_read_header() before any data is actually read. See
6107 libjpeg.doc from the JPEG lib distribution. */
6110 our_common_init_source (j_decompress_ptr cinfo
)
6115 /* Method to terminate data source. Called by
6116 jpeg_finish_decompress() after all data has been processed. */
6119 our_common_term_source (j_decompress_ptr cinfo
)
6124 /* Fill input buffer method for JPEG data source manager. Called
6125 whenever more data is needed. We read the whole image in one step,
6126 so this only adds a fake end of input marker at the end. */
6128 static JOCTET our_memory_buffer
[2];
6131 our_memory_fill_input_buffer (j_decompress_ptr cinfo
)
6133 /* Insert a fake EOI marker. */
6134 struct jpeg_source_mgr
*src
= cinfo
->src
;
6136 our_memory_buffer
[0] = (JOCTET
) 0xFF;
6137 our_memory_buffer
[1] = (JOCTET
) JPEG_EOI
;
6139 src
->next_input_byte
= our_memory_buffer
;
6140 src
->bytes_in_buffer
= 2;
6145 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6146 is the JPEG data source manager. */
6149 our_memory_skip_input_data (j_decompress_ptr cinfo
, long int num_bytes
)
6151 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6155 if (num_bytes
> src
->bytes_in_buffer
)
6156 ERREXIT (cinfo
, JERR_INPUT_EOF
);
6158 src
->bytes_in_buffer
-= num_bytes
;
6159 src
->next_input_byte
+= num_bytes
;
6164 /* Set up the JPEG lib for reading an image from DATA which contains
6165 LEN bytes. CINFO is the decompression info structure created for
6166 reading the image. */
6169 jpeg_memory_src (j_decompress_ptr cinfo
, JOCTET
*data
, unsigned int len
)
6171 struct jpeg_source_mgr
*src
;
6173 if (cinfo
->src
== NULL
)
6175 /* First time for this JPEG object? */
6176 cinfo
->src
= (struct jpeg_source_mgr
*)
6177 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6178 sizeof (struct jpeg_source_mgr
));
6179 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6180 src
->next_input_byte
= data
;
6183 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6184 src
->init_source
= our_common_init_source
;
6185 src
->fill_input_buffer
= our_memory_fill_input_buffer
;
6186 src
->skip_input_data
= our_memory_skip_input_data
;
6187 src
->resync_to_restart
= jpeg_resync_to_restart_wrapper
; /* Use default method. */
6188 src
->term_source
= our_common_term_source
;
6189 src
->bytes_in_buffer
= len
;
6190 src
->next_input_byte
= data
;
6194 struct jpeg_stdio_mgr
6196 struct jpeg_source_mgr mgr
;
6203 /* Size of buffer to read JPEG from file.
6204 Not too big, as we want to use alloc_small. */
6205 #define JPEG_STDIO_BUFFER_SIZE 8192
6208 /* Fill input buffer method for JPEG data source manager. Called
6209 whenever more data is needed. The data is read from a FILE *. */
6212 our_stdio_fill_input_buffer (j_decompress_ptr cinfo
)
6214 struct jpeg_stdio_mgr
*src
;
6216 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6221 bytes
= fread (src
->buffer
, 1, JPEG_STDIO_BUFFER_SIZE
, src
->file
);
6223 src
->mgr
.bytes_in_buffer
= bytes
;
6226 WARNMS (cinfo
, JWRN_JPEG_EOF
);
6228 src
->buffer
[0] = (JOCTET
) 0xFF;
6229 src
->buffer
[1] = (JOCTET
) JPEG_EOI
;
6230 src
->mgr
.bytes_in_buffer
= 2;
6232 src
->mgr
.next_input_byte
= src
->buffer
;
6239 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6240 is the JPEG data source manager. */
6243 our_stdio_skip_input_data (j_decompress_ptr cinfo
, long int num_bytes
)
6245 struct jpeg_stdio_mgr
*src
;
6246 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6248 while (num_bytes
> 0 && !src
->finished
)
6250 if (num_bytes
<= src
->mgr
.bytes_in_buffer
)
6252 src
->mgr
.bytes_in_buffer
-= num_bytes
;
6253 src
->mgr
.next_input_byte
+= num_bytes
;
6258 num_bytes
-= src
->mgr
.bytes_in_buffer
;
6259 src
->mgr
.bytes_in_buffer
= 0;
6260 src
->mgr
.next_input_byte
= NULL
;
6262 our_stdio_fill_input_buffer (cinfo
);
6268 /* Set up the JPEG lib for reading an image from a FILE *.
6269 CINFO is the decompression info structure created for
6270 reading the image. */
6273 jpeg_file_src (j_decompress_ptr cinfo
, FILE *fp
)
6275 struct jpeg_stdio_mgr
*src
;
6277 if (cinfo
->src
!= NULL
)
6278 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6281 /* First time for this JPEG object? */
6282 cinfo
->src
= (struct jpeg_source_mgr
*)
6283 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6284 sizeof (struct jpeg_stdio_mgr
));
6285 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6286 src
->buffer
= (JOCTET
*)
6287 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6288 JPEG_STDIO_BUFFER_SIZE
);
6293 src
->mgr
.init_source
= our_common_init_source
;
6294 src
->mgr
.fill_input_buffer
= our_stdio_fill_input_buffer
;
6295 src
->mgr
.skip_input_data
= our_stdio_skip_input_data
;
6296 src
->mgr
.resync_to_restart
= jpeg_resync_to_restart_wrapper
; /* Use default method. */
6297 src
->mgr
.term_source
= our_common_term_source
;
6298 src
->mgr
.bytes_in_buffer
= 0;
6299 src
->mgr
.next_input_byte
= NULL
;
6303 /* Load image IMG for use on frame F. Patterned after example.c
6304 from the JPEG lib. */
6307 jpeg_load (struct frame
*f
, struct image
*img
)
6309 struct jpeg_decompress_struct cinfo
;
6310 struct my_jpeg_error_mgr mgr
;
6311 Lisp_Object file
, specified_file
;
6312 Lisp_Object specified_data
;
6313 FILE * volatile fp
= NULL
;
6315 int row_stride
, x
, y
;
6316 XImagePtr ximg
= NULL
;
6318 unsigned long *colors
;
6320 struct gcpro gcpro1
;
6322 /* Open the JPEG file. */
6323 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6324 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6328 if (NILP (specified_data
))
6330 file
= x_find_image_file (specified_file
);
6331 if (!STRINGP (file
))
6333 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6338 fp
= fopen (SDATA (file
), "rb");
6341 image_error ("Cannot open `%s'", file
, Qnil
);
6347 /* Customize libjpeg's error handling to call my_error_exit when an
6348 error is detected. This function will perform a longjmp.
6349 Casting return value avoids a GCC warning on W32. */
6350 cinfo
.err
= (struct jpeg_error_mgr
*)fn_jpeg_std_error (&mgr
.pub
);
6351 mgr
.pub
.error_exit
= my_error_exit
;
6353 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
6357 /* Called from my_error_exit. Display a JPEG error. */
6358 char buffer
[JMSG_LENGTH_MAX
];
6359 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
6360 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
6361 build_string (buffer
));
6364 /* Close the input file and destroy the JPEG object. */
6366 fclose ((FILE *) fp
);
6367 fn_jpeg_destroy_decompress (&cinfo
);
6369 /* If we already have an XImage, free that. */
6370 x_destroy_x_image (ximg
);
6372 /* Free pixmap and colors. */
6373 x_clear_image (f
, img
);
6379 /* Create the JPEG decompression object. Let it read from fp.
6380 Read the JPEG image header. */
6381 fn_jpeg_CreateDecompress (&cinfo
, JPEG_LIB_VERSION
, sizeof (cinfo
));
6383 if (NILP (specified_data
))
6384 jpeg_file_src (&cinfo
, (FILE *) fp
);
6386 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
6387 SBYTES (specified_data
));
6389 fn_jpeg_read_header (&cinfo
, 1);
6391 /* Customize decompression so that color quantization will be used.
6392 Start decompression. */
6393 cinfo
.quantize_colors
= 1;
6394 fn_jpeg_start_decompress (&cinfo
);
6395 width
= img
->width
= cinfo
.output_width
;
6396 height
= img
->height
= cinfo
.output_height
;
6398 if (!check_image_size (f
, width
, height
))
6400 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
6401 longjmp (mgr
.setjmp_buffer
, 2);
6404 /* Create X image and pixmap. */
6405 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
6406 longjmp (mgr
.setjmp_buffer
, 2);
6408 /* Allocate colors. When color quantization is used,
6409 cinfo.actual_number_of_colors has been set with the number of
6410 colors generated, and cinfo.colormap is a two-dimensional array
6411 of color indices in the range 0..cinfo.actual_number_of_colors.
6412 No more than 255 colors will be generated. */
6416 if (cinfo
.out_color_components
> 2)
6417 ir
= 0, ig
= 1, ib
= 2;
6418 else if (cinfo
.out_color_components
> 1)
6419 ir
= 0, ig
= 1, ib
= 0;
6421 ir
= 0, ig
= 0, ib
= 0;
6423 /* Use the color table mechanism because it handles colors that
6424 cannot be allocated nicely. Such colors will be replaced with
6425 a default color, and we don't have to care about which colors
6426 can be freed safely, and which can't. */
6427 init_color_table ();
6428 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
6431 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
6433 /* Multiply RGB values with 255 because X expects RGB values
6434 in the range 0..0xffff. */
6435 int r
= cinfo
.colormap
[ir
][i
] << 8;
6436 int g
= cinfo
.colormap
[ig
][i
] << 8;
6437 int b
= cinfo
.colormap
[ib
][i
] << 8;
6438 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
6441 #ifdef COLOR_TABLE_SUPPORT
6442 /* Remember those colors actually allocated. */
6443 img
->colors
= colors_in_color_table (&img
->ncolors
);
6444 free_color_table ();
6445 #endif /* COLOR_TABLE_SUPPORT */
6449 row_stride
= width
* cinfo
.output_components
;
6450 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
6452 for (y
= 0; y
< height
; ++y
)
6454 fn_jpeg_read_scanlines (&cinfo
, buffer
, 1);
6455 for (x
= 0; x
< cinfo
.output_width
; ++x
)
6456 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
6460 fn_jpeg_finish_decompress (&cinfo
);
6461 fn_jpeg_destroy_decompress (&cinfo
);
6463 fclose ((FILE *) fp
);
6465 /* Maybe fill in the background field while we have ximg handy. */
6466 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6467 /* Casting avoids a GCC warning. */
6468 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6470 /* Put the image into the pixmap. */
6471 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6472 x_destroy_x_image (ximg
);
6477 #else /* HAVE_JPEG */
6481 jpeg_load (struct frame
*f
, struct image
*img
)
6483 return ns_load_image (f
, img
,
6484 image_spec_value (img
->spec
, QCfile
, NULL
),
6485 image_spec_value (img
->spec
, QCdata
, NULL
));
6487 #endif /* HAVE_NS */
6489 #endif /* !HAVE_JPEG */
6493 /***********************************************************************
6495 ***********************************************************************/
6497 #if defined (HAVE_TIFF) || defined (HAVE_NS)
6499 static int tiff_image_p (Lisp_Object object
);
6500 static int tiff_load (struct frame
*f
, struct image
*img
);
6502 /* The symbol `tiff' identifying images of this type. */
6506 /* Indices of image specification fields in tiff_format, below. */
6508 enum tiff_keyword_index
6517 TIFF_HEURISTIC_MASK
,
6524 /* Vector of image_keyword structures describing the format
6525 of valid user-defined image specifications. */
6527 static const struct image_keyword tiff_format
[TIFF_LAST
] =
6529 {":type", IMAGE_SYMBOL_VALUE
, 1},
6530 {":data", IMAGE_STRING_VALUE
, 0},
6531 {":file", IMAGE_STRING_VALUE
, 0},
6532 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6533 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6534 {":relief", IMAGE_INTEGER_VALUE
, 0},
6535 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6536 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6537 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6538 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
6539 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0}
6542 /* Structure describing the image type `tiff'. */
6544 static struct image_type tiff_type
=
6553 /* Return non-zero if OBJECT is a valid TIFF image specification. */
6556 tiff_image_p (Lisp_Object object
)
6558 struct image_keyword fmt
[TIFF_LAST
];
6559 memcpy (fmt
, tiff_format
, sizeof fmt
);
6561 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
6564 /* Must specify either the :data or :file keyword. */
6565 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
6568 #endif /* HAVE_TIFF || HAVE_NS */
6576 /* TIFF library details. */
6577 DEF_IMGLIB_FN (TIFFSetErrorHandler
);
6578 DEF_IMGLIB_FN (TIFFSetWarningHandler
);
6579 DEF_IMGLIB_FN (TIFFOpen
);
6580 DEF_IMGLIB_FN (TIFFClientOpen
);
6581 DEF_IMGLIB_FN (TIFFGetField
);
6582 DEF_IMGLIB_FN (TIFFReadRGBAImage
);
6583 DEF_IMGLIB_FN (TIFFClose
);
6584 DEF_IMGLIB_FN (TIFFSetDirectory
);
6587 init_tiff_functions (Lisp_Object libraries
)
6591 if (!(library
= w32_delayed_load (libraries
, Qtiff
)))
6594 LOAD_IMGLIB_FN (library
, TIFFSetErrorHandler
);
6595 LOAD_IMGLIB_FN (library
, TIFFSetWarningHandler
);
6596 LOAD_IMGLIB_FN (library
, TIFFOpen
);
6597 LOAD_IMGLIB_FN (library
, TIFFClientOpen
);
6598 LOAD_IMGLIB_FN (library
, TIFFGetField
);
6599 LOAD_IMGLIB_FN (library
, TIFFReadRGBAImage
);
6600 LOAD_IMGLIB_FN (library
, TIFFClose
);
6601 LOAD_IMGLIB_FN (library
, TIFFSetDirectory
);
6607 #define fn_TIFFSetErrorHandler TIFFSetErrorHandler
6608 #define fn_TIFFSetWarningHandler TIFFSetWarningHandler
6609 #define fn_TIFFOpen TIFFOpen
6610 #define fn_TIFFClientOpen TIFFClientOpen
6611 #define fn_TIFFGetField TIFFGetField
6612 #define fn_TIFFReadRGBAImage TIFFReadRGBAImage
6613 #define fn_TIFFClose TIFFClose
6614 #define fn_TIFFSetDirectory TIFFSetDirectory
6615 #endif /* HAVE_NTGUI */
6618 /* Reading from a memory buffer for TIFF images Based on the PNG
6619 memory source, but we have to provide a lot of extra functions.
6622 We really only need to implement read and seek, but I am not
6623 convinced that the TIFF library is smart enough not to destroy
6624 itself if we only hand it the function pointers we need to
6629 unsigned char *bytes
;
6636 tiff_read_from_memory (thandle_t data
, tdata_t buf
, tsize_t size
)
6638 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6640 if (size
> src
->len
- src
->index
)
6642 memcpy (buf
, src
->bytes
+ src
->index
, size
);
6648 tiff_write_from_memory (thandle_t data
, tdata_t buf
, tsize_t size
)
6654 tiff_seek_in_memory (thandle_t data
, toff_t off
, int whence
)
6656 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6661 case SEEK_SET
: /* Go from beginning of source. */
6665 case SEEK_END
: /* Go from end of source. */
6666 idx
= src
->len
+ off
;
6669 case SEEK_CUR
: /* Go from current position. */
6670 idx
= src
->index
+ off
;
6673 default: /* Invalid `whence'. */
6677 if (idx
> src
->len
|| idx
< 0)
6685 tiff_close_memory (thandle_t data
)
6692 tiff_mmap_memory (thandle_t data
, tdata_t
*pbase
, toff_t
*psize
)
6694 /* It is already _IN_ memory. */
6699 tiff_unmap_memory (thandle_t data
, tdata_t base
, toff_t size
)
6701 /* We don't need to do this. */
6705 tiff_size_of_memory (thandle_t data
)
6707 return ((tiff_memory_source
*) data
)->len
;
6712 tiff_error_handler (const char *title
, const char *format
, va_list ap
)
6717 len
= sprintf (buf
, "TIFF error: %s ", title
);
6718 vsprintf (buf
+ len
, format
, ap
);
6719 add_to_log (buf
, Qnil
, Qnil
);
6724 tiff_warning_handler (const char *title
, const char *format
, va_list ap
)
6729 len
= sprintf (buf
, "TIFF warning: %s ", title
);
6730 vsprintf (buf
+ len
, format
, ap
);
6731 add_to_log (buf
, Qnil
, Qnil
);
6735 /* Load TIFF image IMG for use on frame F. Value is non-zero if
6739 tiff_load (struct frame
*f
, struct image
*img
)
6741 Lisp_Object file
, specified_file
;
6742 Lisp_Object specified_data
;
6744 int width
, height
, x
, y
, count
;
6748 struct gcpro gcpro1
;
6749 tiff_memory_source memsrc
;
6752 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6753 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6757 fn_TIFFSetErrorHandler (tiff_error_handler
);
6758 fn_TIFFSetWarningHandler (tiff_warning_handler
);
6760 if (NILP (specified_data
))
6762 /* Read from a file */
6763 file
= x_find_image_file (specified_file
);
6764 if (!STRINGP (file
))
6766 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6771 /* Try to open the image file. Casting return value avoids a
6772 GCC warning on W32. */
6773 tiff
= (TIFF
*)fn_TIFFOpen (SDATA (file
), "r");
6776 image_error ("Cannot open `%s'", file
, Qnil
);
6783 /* Memory source! */
6784 memsrc
.bytes
= SDATA (specified_data
);
6785 memsrc
.len
= SBYTES (specified_data
);
6788 /* Casting return value avoids a GCC warning on W32. */
6789 tiff
= (TIFF
*)fn_TIFFClientOpen ("memory_source", "r", &memsrc
,
6790 (TIFFReadWriteProc
) tiff_read_from_memory
,
6791 (TIFFReadWriteProc
) tiff_write_from_memory
,
6792 tiff_seek_in_memory
,
6794 tiff_size_of_memory
,
6800 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
6806 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
6807 if (INTEGERP (image
))
6809 int ino
= XFASTINT (image
);
6810 if (!fn_TIFFSetDirectory (tiff
, ino
))
6812 image_error ("Invalid image number `%s' in image `%s'",
6814 fn_TIFFClose (tiff
);
6820 /* Get width and height of the image, and allocate a raster buffer
6821 of width x height 32-bit values. */
6822 fn_TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
6823 fn_TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
6825 if (!check_image_size (f
, width
, height
))
6827 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
6828 fn_TIFFClose (tiff
);
6833 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
6835 rc
= fn_TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
6837 /* Count the number of images in the file. */
6838 for (count
= 1, rc2
= 1; rc2
; count
++)
6839 rc2
= fn_TIFFSetDirectory (tiff
, count
);
6842 img
->data
.lisp_val
= Fcons (Qcount
,
6843 Fcons (make_number (count
),
6844 img
->data
.lisp_val
));
6846 fn_TIFFClose (tiff
);
6849 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
6855 /* Create the X image and pixmap. */
6856 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
6863 /* Initialize the color table. */
6864 init_color_table ();
6866 /* Process the pixel raster. Origin is in the lower-left corner. */
6867 for (y
= 0; y
< height
; ++y
)
6869 uint32
*row
= buf
+ y
* width
;
6871 for (x
= 0; x
< width
; ++x
)
6873 uint32 abgr
= row
[x
];
6874 int r
= TIFFGetR (abgr
) << 8;
6875 int g
= TIFFGetG (abgr
) << 8;
6876 int b
= TIFFGetB (abgr
) << 8;
6877 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
6881 #ifdef COLOR_TABLE_SUPPORT
6882 /* Remember the colors allocated for the image. Free the color table. */
6883 img
->colors
= colors_in_color_table (&img
->ncolors
);
6884 free_color_table ();
6885 #endif /* COLOR_TABLE_SUPPORT */
6888 img
->height
= height
;
6890 /* Maybe fill in the background field while we have ximg handy. */
6891 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6892 /* Casting avoids a GCC warning on W32. */
6893 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6895 /* Put the image into the pixmap, then free the X image and its buffer. */
6896 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6897 x_destroy_x_image (ximg
);
6904 #else /* HAVE_TIFF */
6908 tiff_load (struct frame
*f
, struct image
*img
)
6910 return ns_load_image (f
, img
,
6911 image_spec_value (img
->spec
, QCfile
, NULL
),
6912 image_spec_value (img
->spec
, QCdata
, NULL
));
6914 #endif /* HAVE_NS */
6916 #endif /* !HAVE_TIFF */
6920 /***********************************************************************
6922 ***********************************************************************/
6924 #if defined (HAVE_GIF) || defined (HAVE_NS)
6926 static int gif_image_p (Lisp_Object object
);
6927 static int gif_load (struct frame
*f
, struct image
*img
);
6928 static void gif_clear_image (struct frame
*f
, struct image
*img
);
6930 /* The symbol `gif' identifying images of this type. */
6934 /* Indices of image specification fields in gif_format, below. */
6936 enum gif_keyword_index
6952 /* Vector of image_keyword structures describing the format
6953 of valid user-defined image specifications. */
6955 static const struct image_keyword gif_format
[GIF_LAST
] =
6957 {":type", IMAGE_SYMBOL_VALUE
, 1},
6958 {":data", IMAGE_STRING_VALUE
, 0},
6959 {":file", IMAGE_STRING_VALUE
, 0},
6960 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6961 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6962 {":relief", IMAGE_INTEGER_VALUE
, 0},
6963 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6964 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6965 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6966 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6967 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
6970 /* Structure describing the image type `gif'. */
6972 static struct image_type gif_type
=
6981 /* Free X resources of GIF image IMG which is used on frame F. */
6984 gif_clear_image (struct frame
*f
, struct image
*img
)
6986 /* IMG->data.ptr_val may contain metadata with extension data. */
6987 img
->data
.lisp_val
= Qnil
;
6988 x_clear_image (f
, img
);
6991 /* Return non-zero if OBJECT is a valid GIF image specification. */
6994 gif_image_p (Lisp_Object object
)
6996 struct image_keyword fmt
[GIF_LAST
];
6997 memcpy (fmt
, gif_format
, sizeof fmt
);
6999 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
7002 /* Must specify either the :data or :file keyword. */
7003 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
7006 #endif /* HAVE_GIF */
7010 #if defined (HAVE_NTGUI)
7011 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
7012 Undefine before redefining to avoid a preprocessor warning. */
7016 /* avoid conflict with QuickdrawText.h */
7017 #define DrawText gif_DrawText
7018 #include <gif_lib.h>
7021 #else /* HAVE_NTGUI */
7023 #include <gif_lib.h>
7025 #endif /* HAVE_NTGUI */
7030 /* GIF library details. */
7031 DEF_IMGLIB_FN (DGifCloseFile
);
7032 DEF_IMGLIB_FN (DGifSlurp
);
7033 DEF_IMGLIB_FN (DGifOpen
);
7034 DEF_IMGLIB_FN (DGifOpenFileName
);
7037 init_gif_functions (Lisp_Object libraries
)
7041 if (!(library
= w32_delayed_load (libraries
, Qgif
)))
7044 LOAD_IMGLIB_FN (library
, DGifCloseFile
);
7045 LOAD_IMGLIB_FN (library
, DGifSlurp
);
7046 LOAD_IMGLIB_FN (library
, DGifOpen
);
7047 LOAD_IMGLIB_FN (library
, DGifOpenFileName
);
7053 #define fn_DGifCloseFile DGifCloseFile
7054 #define fn_DGifSlurp DGifSlurp
7055 #define fn_DGifOpen DGifOpen
7056 #define fn_DGifOpenFileName DGifOpenFileName
7058 #endif /* HAVE_NTGUI */
7060 /* Reading a GIF image from memory
7061 Based on the PNG memory stuff to a certain extent. */
7065 unsigned char *bytes
;
7071 /* Make the current memory source available to gif_read_from_memory.
7072 It's done this way because not all versions of libungif support
7073 a UserData field in the GifFileType structure. */
7074 static gif_memory_source
*current_gif_memory_src
;
7077 gif_read_from_memory (GifFileType
*file
, GifByteType
*buf
, int len
)
7079 gif_memory_source
*src
= current_gif_memory_src
;
7081 if (len
> src
->len
- src
->index
)
7084 memcpy (buf
, src
->bytes
+ src
->index
, len
);
7090 /* Load GIF image IMG for use on frame F. Value is non-zero if
7093 static const int interlace_start
[] = {0, 4, 2, 1};
7094 static const int interlace_increment
[] = {8, 8, 4, 2};
7097 gif_load (struct frame
*f
, struct image
*img
)
7099 Lisp_Object file
, specified_file
;
7100 Lisp_Object specified_data
;
7101 int rc
, width
, height
, x
, y
, i
;
7103 ColorMapObject
*gif_color_map
;
7104 unsigned long pixel_colors
[256];
7106 struct gcpro gcpro1
;
7108 int ino
, image_height
, image_width
;
7109 gif_memory_source memsrc
;
7110 unsigned char *raster
;
7112 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7113 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7117 if (NILP (specified_data
))
7119 file
= x_find_image_file (specified_file
);
7120 if (!STRINGP (file
))
7122 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7127 /* Open the GIF file. Casting return value avoids a GCC warning
7129 gif
= (GifFileType
*)fn_DGifOpenFileName (SDATA (file
));
7132 image_error ("Cannot open `%s'", file
, Qnil
);
7139 /* Read from memory! */
7140 current_gif_memory_src
= &memsrc
;
7141 memsrc
.bytes
= SDATA (specified_data
);
7142 memsrc
.len
= SBYTES (specified_data
);
7145 /* Casting return value avoids a GCC warning on W32. */
7146 gif
= (GifFileType
*) fn_DGifOpen (&memsrc
, gif_read_from_memory
);
7149 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
7155 /* Before reading entire contents, check the declared image size. */
7156 if (!check_image_size (f
, gif
->SWidth
, gif
->SHeight
))
7158 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7159 fn_DGifCloseFile (gif
);
7164 /* Read entire contents. */
7165 rc
= fn_DGifSlurp (gif
);
7166 if (rc
== GIF_ERROR
)
7168 image_error ("Error reading `%s'", img
->spec
, Qnil
);
7169 fn_DGifCloseFile (gif
);
7174 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
7175 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
7176 if (ino
>= gif
->ImageCount
)
7178 image_error ("Invalid image number `%s' in image `%s'",
7180 fn_DGifCloseFile (gif
);
7185 img
->corners
[TOP_CORNER
] = gif
->SavedImages
[ino
].ImageDesc
.Top
;
7186 img
->corners
[LEFT_CORNER
] = gif
->SavedImages
[ino
].ImageDesc
.Left
;
7187 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
7188 img
->corners
[BOT_CORNER
] = img
->corners
[TOP_CORNER
] + image_height
;
7189 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
7190 img
->corners
[RIGHT_CORNER
] = img
->corners
[LEFT_CORNER
] + image_width
;
7192 width
= img
->width
= max (gif
->SWidth
,
7193 max (gif
->Image
.Left
+ gif
->Image
.Width
,
7194 img
->corners
[RIGHT_CORNER
]));
7195 height
= img
->height
= max (gif
->SHeight
,
7196 max (gif
->Image
.Top
+ gif
->Image
.Height
,
7197 img
->corners
[BOT_CORNER
]));
7199 if (!check_image_size (f
, width
, height
))
7201 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7202 fn_DGifCloseFile (gif
);
7207 /* Create the X image and pixmap. */
7208 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
7210 fn_DGifCloseFile (gif
);
7215 /* Allocate colors. */
7216 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
7218 gif_color_map
= gif
->SColorMap
;
7219 init_color_table ();
7220 memset (pixel_colors
, 0, sizeof pixel_colors
);
7223 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
7225 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
7226 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
7227 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
7228 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
7231 #ifdef COLOR_TABLE_SUPPORT
7232 img
->colors
= colors_in_color_table (&img
->ncolors
);
7233 free_color_table ();
7234 #endif /* COLOR_TABLE_SUPPORT */
7236 /* Clear the part of the screen image that are not covered by
7237 the image from the GIF file. Full animated GIF support
7238 requires more than can be done here (see the gif89 spec,
7239 disposal methods). Let's simply assume that the part
7240 not covered by a sub-image is in the frame's background color. */
7241 for (y
= 0; y
< img
->corners
[TOP_CORNER
]; ++y
)
7242 for (x
= 0; x
< width
; ++x
)
7243 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7245 for (y
= img
->corners
[BOT_CORNER
]; y
< height
; ++y
)
7246 for (x
= 0; x
< width
; ++x
)
7247 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7249 for (y
= img
->corners
[TOP_CORNER
]; y
< img
->corners
[BOT_CORNER
]; ++y
)
7251 for (x
= 0; x
< img
->corners
[LEFT_CORNER
]; ++x
)
7252 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7253 for (x
= img
->corners
[RIGHT_CORNER
]; x
< width
; ++x
)
7254 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7257 /* Read the GIF image into the X image. We use a local variable
7258 `raster' here because RasterBits below is a char *, and invites
7259 problems with bytes >= 0x80. */
7260 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
7262 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
7265 int row
= interlace_start
[0];
7269 for (y
= 0; y
< image_height
; y
++)
7271 if (row
>= image_height
)
7273 row
= interlace_start
[++pass
];
7274 while (row
>= image_height
)
7275 row
= interlace_start
[++pass
];
7278 for (x
= 0; x
< image_width
; x
++)
7280 int i
= raster
[(y
* image_width
) + x
];
7281 XPutPixel (ximg
, x
+ img
->corners
[LEFT_CORNER
],
7282 row
+ img
->corners
[TOP_CORNER
], pixel_colors
[i
]);
7285 row
+= interlace_increment
[pass
];
7290 for (y
= 0; y
< image_height
; ++y
)
7291 for (x
= 0; x
< image_width
; ++x
)
7293 int i
= raster
[y
* image_width
+ x
];
7294 XPutPixel (ximg
, x
+ img
->corners
[LEFT_CORNER
],
7295 y
+ img
->corners
[TOP_CORNER
], pixel_colors
[i
]);
7299 /* Save GIF image extension data for `image-metadata'.
7300 Format is (count IMAGES extension-data (FUNCTION "BYTES" ...)). */
7301 img
->data
.lisp_val
= Qnil
;
7302 if (gif
->SavedImages
[ino
].ExtensionBlockCount
> 0)
7304 ExtensionBlock
*ext
= gif
->SavedImages
[ino
].ExtensionBlocks
;
7305 for (i
= 0; i
< gif
->SavedImages
[ino
].ExtensionBlockCount
; i
++, ext
++)
7306 /* Append (... FUNCTION "BYTES") */
7307 img
->data
.lisp_val
= Fcons (make_unibyte_string (ext
->Bytes
, ext
->ByteCount
),
7308 Fcons (make_number (ext
->Function
),
7309 img
->data
.lisp_val
));
7310 img
->data
.lisp_val
= Fcons (Qextension_data
,
7311 Fcons (Fnreverse (img
->data
.lisp_val
),
7314 if (gif
->ImageCount
> 1)
7315 img
->data
.lisp_val
= Fcons (Qcount
,
7316 Fcons (make_number (gif
->ImageCount
),
7317 img
->data
.lisp_val
));
7319 fn_DGifCloseFile (gif
);
7321 /* Maybe fill in the background field while we have ximg handy. */
7322 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7323 /* Casting avoids a GCC warning. */
7324 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
7326 /* Put the image into the pixmap, then free the X image and its buffer. */
7327 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7328 x_destroy_x_image (ximg
);
7334 #else /* !HAVE_GIF */
7338 gif_load (struct frame
*f
, struct image
*img
)
7340 return ns_load_image (f
, img
,
7341 image_spec_value (img
->spec
, QCfile
, NULL
),
7342 image_spec_value (img
->spec
, QCdata
, NULL
));
7344 #endif /* HAVE_NS */
7346 #endif /* HAVE_GIF */
7350 /***********************************************************************
7352 ***********************************************************************/
7354 #if defined (HAVE_RSVG)
7356 /* Function prototypes. */
7358 static int svg_image_p (Lisp_Object object
);
7359 static int svg_load (struct frame
*f
, struct image
*img
);
7361 static int svg_load_image (struct frame
*, struct image
*,
7362 unsigned char *, unsigned int);
7364 /* The symbol `svg' identifying images of this type. */
7368 /* Indices of image specification fields in svg_format, below. */
7370 enum svg_keyword_index
7385 /* Vector of image_keyword structures describing the format
7386 of valid user-defined image specifications. */
7388 static const struct image_keyword svg_format
[SVG_LAST
] =
7390 {":type", IMAGE_SYMBOL_VALUE
, 1},
7391 {":data", IMAGE_STRING_VALUE
, 0},
7392 {":file", IMAGE_STRING_VALUE
, 0},
7393 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7394 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7395 {":relief", IMAGE_INTEGER_VALUE
, 0},
7396 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7397 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7398 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7399 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7402 /* Structure describing the image type `svg'. Its the same type of
7403 structure defined for all image formats, handled by emacs image
7404 functions. See struct image_type in dispextern.h. */
7406 static struct image_type svg_type
=
7408 /* An identifier showing that this is an image structure for the SVG format. */
7410 /* Handle to a function that can be used to identify a SVG file. */
7412 /* Handle to function used to load a SVG file. */
7414 /* Handle to function to free sresources for SVG. */
7416 /* An internal field to link to the next image type in a list of
7417 image types, will be filled in when registering the format. */
7422 /* Return non-zero if OBJECT is a valid SVG image specification. Do
7423 this by calling parse_image_spec and supplying the keywords that
7424 identify the SVG format. */
7427 svg_image_p (Lisp_Object object
)
7429 struct image_keyword fmt
[SVG_LAST
];
7430 memcpy (fmt
, svg_format
, sizeof fmt
);
7432 if (!parse_image_spec (object
, fmt
, SVG_LAST
, Qsvg
))
7435 /* Must specify either the :data or :file keyword. */
7436 return fmt
[SVG_FILE
].count
+ fmt
[SVG_DATA
].count
== 1;
7439 #include <librsvg/rsvg.h>
7443 /* SVG library functions. */
7444 DEF_IMGLIB_FN (rsvg_handle_new
);
7445 DEF_IMGLIB_FN (rsvg_handle_get_dimensions
);
7446 DEF_IMGLIB_FN (rsvg_handle_write
);
7447 DEF_IMGLIB_FN (rsvg_handle_close
);
7448 DEF_IMGLIB_FN (rsvg_handle_get_pixbuf
);
7449 DEF_IMGLIB_FN (rsvg_handle_free
);
7451 DEF_IMGLIB_FN (gdk_pixbuf_get_width
);
7452 DEF_IMGLIB_FN (gdk_pixbuf_get_height
);
7453 DEF_IMGLIB_FN (gdk_pixbuf_get_pixels
);
7454 DEF_IMGLIB_FN (gdk_pixbuf_get_rowstride
);
7455 DEF_IMGLIB_FN (gdk_pixbuf_get_colorspace
);
7456 DEF_IMGLIB_FN (gdk_pixbuf_get_n_channels
);
7457 DEF_IMGLIB_FN (gdk_pixbuf_get_has_alpha
);
7458 DEF_IMGLIB_FN (gdk_pixbuf_get_bits_per_sample
);
7460 DEF_IMGLIB_FN (g_type_init
);
7461 DEF_IMGLIB_FN (g_object_unref
);
7462 DEF_IMGLIB_FN (g_error_free
);
7464 Lisp_Object Qgdk_pixbuf
, Qglib
, Qgobject
;
7467 init_svg_functions (Lisp_Object libraries
)
7469 HMODULE library
, gdklib
, glib
, gobject
;
7471 if (!(glib
= w32_delayed_load (libraries
, Qglib
))
7472 || !(gobject
= w32_delayed_load (libraries
, Qgobject
))
7473 || !(gdklib
= w32_delayed_load (libraries
, Qgdk_pixbuf
))
7474 || !(library
= w32_delayed_load (libraries
, Qsvg
)))
7477 LOAD_IMGLIB_FN (library
, rsvg_handle_new
);
7478 LOAD_IMGLIB_FN (library
, rsvg_handle_get_dimensions
);
7479 LOAD_IMGLIB_FN (library
, rsvg_handle_write
);
7480 LOAD_IMGLIB_FN (library
, rsvg_handle_close
);
7481 LOAD_IMGLIB_FN (library
, rsvg_handle_get_pixbuf
);
7482 LOAD_IMGLIB_FN (library
, rsvg_handle_free
);
7484 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_width
);
7485 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_height
);
7486 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_pixels
);
7487 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_rowstride
);
7488 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_colorspace
);
7489 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_n_channels
);
7490 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_has_alpha
);
7491 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_bits_per_sample
);
7493 LOAD_IMGLIB_FN (gobject
, g_type_init
);
7494 LOAD_IMGLIB_FN (gobject
, g_object_unref
);
7495 LOAD_IMGLIB_FN (glib
, g_error_free
);
7501 /* The following aliases for library functions allow dynamic loading
7502 to be used on some platforms. */
7503 #define fn_rsvg_handle_new rsvg_handle_new
7504 #define fn_rsvg_handle_get_dimensions rsvg_handle_get_dimensions
7505 #define fn_rsvg_handle_write rsvg_handle_write
7506 #define fn_rsvg_handle_close rsvg_handle_close
7507 #define fn_rsvg_handle_get_pixbuf rsvg_handle_get_pixbuf
7508 #define fn_rsvg_handle_free rsvg_handle_free
7510 #define fn_gdk_pixbuf_get_width gdk_pixbuf_get_width
7511 #define fn_gdk_pixbuf_get_height gdk_pixbuf_get_height
7512 #define fn_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels
7513 #define fn_gdk_pixbuf_get_rowstride gdk_pixbuf_get_rowstride
7514 #define fn_gdk_pixbuf_get_colorspace gdk_pixbuf_get_colorspace
7515 #define fn_gdk_pixbuf_get_n_channels gdk_pixbuf_get_n_channels
7516 #define fn_gdk_pixbuf_get_has_alpha gdk_pixbuf_get_has_alpha
7517 #define fn_gdk_pixbuf_get_bits_per_sample gdk_pixbuf_get_bits_per_sample
7519 #define fn_g_type_init g_type_init
7520 #define fn_g_object_unref g_object_unref
7521 #define fn_g_error_free g_error_free
7522 #endif /* !HAVE_NTGUI */
7524 /* Load SVG image IMG for use on frame F. Value is non-zero if
7525 successful. this function will go into the svg_type structure, and
7526 the prototype thus needs to be compatible with that structure. */
7529 svg_load (struct frame
*f
, struct image
*img
)
7532 Lisp_Object file_name
;
7534 /* If IMG->spec specifies a file name, create a non-file spec from it. */
7535 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
7536 if (STRINGP (file_name
))
7539 unsigned char *contents
;
7541 struct gcpro gcpro1
;
7543 file
= x_find_image_file (file_name
);
7545 if (!STRINGP (file
))
7547 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
7552 /* Read the entire file into memory. */
7553 contents
= slurp_file (SDATA (file
), &size
);
7554 if (contents
== NULL
)
7556 image_error ("Error loading SVG image `%s'", img
->spec
, Qnil
);
7560 /* If the file was slurped into memory properly, parse it. */
7561 success_p
= svg_load_image (f
, img
, contents
, size
);
7565 /* Else its not a file, its a lisp object. Load the image from a
7566 lisp object rather than a file. */
7571 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7572 success_p
= svg_load_image (f
, img
, SDATA (data
), SBYTES (data
));
7578 /* svg_load_image is a helper function for svg_load, which does the
7579 actual loading given contents and size, apart from frame and image
7580 structures, passed from svg_load.
7582 Uses librsvg to do most of the image processing.
7584 Returns non-zero when successful. */
7586 svg_load_image (struct frame
*f
, /* Pointer to emacs frame structure. */
7587 struct image
*img
, /* Pointer to emacs image structure. */
7588 unsigned char *contents
, /* String containing the SVG XML data to be parsed. */
7589 unsigned int size
) /* Size of data in bytes. */
7591 RsvgHandle
*rsvg_handle
;
7592 RsvgDimensionData dimension_data
;
7593 GError
*error
= NULL
;
7597 const guint8
*pixels
;
7600 Lisp_Object specified_bg
;
7605 /* g_type_init is a glib function that must be called prior to using
7606 gnome type library functions. */
7608 /* Make a handle to a new rsvg object. */
7609 rsvg_handle
= (RsvgHandle
*) fn_rsvg_handle_new ();
7611 /* Parse the contents argument and fill in the rsvg_handle. */
7612 fn_rsvg_handle_write (rsvg_handle
, contents
, size
, &error
);
7613 if (error
) goto rsvg_error
;
7615 /* The parsing is complete, rsvg_handle is ready to used, close it
7616 for further writes. */
7617 fn_rsvg_handle_close (rsvg_handle
, &error
);
7618 if (error
) goto rsvg_error
;
7620 fn_rsvg_handle_get_dimensions (rsvg_handle
, &dimension_data
);
7621 if (! check_image_size (f
, dimension_data
.width
, dimension_data
.height
))
7623 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7627 /* We can now get a valid pixel buffer from the svg file, if all
7629 pixbuf
= (GdkPixbuf
*) fn_rsvg_handle_get_pixbuf (rsvg_handle
);
7630 if (!pixbuf
) goto rsvg_error
;
7631 fn_g_object_unref (rsvg_handle
);
7633 /* Extract some meta data from the svg handle. */
7634 width
= fn_gdk_pixbuf_get_width (pixbuf
);
7635 height
= fn_gdk_pixbuf_get_height (pixbuf
);
7636 pixels
= (const guint8
*) fn_gdk_pixbuf_get_pixels (pixbuf
);
7637 rowstride
= fn_gdk_pixbuf_get_rowstride (pixbuf
);
7639 /* Validate the svg meta data. */
7640 eassert (fn_gdk_pixbuf_get_colorspace (pixbuf
) == GDK_COLORSPACE_RGB
);
7641 eassert (fn_gdk_pixbuf_get_n_channels (pixbuf
) == 4);
7642 eassert (fn_gdk_pixbuf_get_has_alpha (pixbuf
));
7643 eassert (fn_gdk_pixbuf_get_bits_per_sample (pixbuf
) == 8);
7645 /* Try to create a x pixmap to hold the svg pixmap. */
7646 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
7648 fn_g_object_unref (pixbuf
);
7652 init_color_table ();
7654 /* Handle alpha channel by combining the image with a background
7656 specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
7657 if (!STRINGP (specified_bg
)
7658 || !x_defined_color (f
, SDATA (specified_bg
), &background
, 0))
7661 background
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
7662 x_query_color (f
, &background
);
7664 ns_query_color (FRAME_BACKGROUND_COLOR (f
), &background
, 1);
7668 /* SVG pixmaps specify transparency in the last byte, so right
7669 shift 8 bits to get rid of it, since emacs doesn't support
7671 background
.red
>>= 8;
7672 background
.green
>>= 8;
7673 background
.blue
>>= 8;
7675 /* This loop handles opacity values, since Emacs assumes
7676 non-transparent images. Each pixel must be "flattened" by
7677 calculating the resulting color, given the transparency of the
7678 pixel, and the image background color. */
7679 for (y
= 0; y
< height
; ++y
)
7681 for (x
= 0; x
< width
; ++x
)
7691 opacity
= *pixels
++;
7693 red
= ((red
* opacity
)
7694 + (background
.red
* ((1 << 8) - opacity
)));
7695 green
= ((green
* opacity
)
7696 + (background
.green
* ((1 << 8) - opacity
)));
7697 blue
= ((blue
* opacity
)
7698 + (background
.blue
* ((1 << 8) - opacity
)));
7700 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, red
, green
, blue
));
7703 pixels
+= rowstride
- 4 * width
;
7706 #ifdef COLOR_TABLE_SUPPORT
7707 /* Remember colors allocated for this image. */
7708 img
->colors
= colors_in_color_table (&img
->ncolors
);
7709 free_color_table ();
7710 #endif /* COLOR_TABLE_SUPPORT */
7712 fn_g_object_unref (pixbuf
);
7715 img
->height
= height
;
7717 /* Maybe fill in the background field while we have ximg handy.
7718 Casting avoids a GCC warning. */
7719 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
7721 /* Put the image into the pixmap, then free the X image and its
7723 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7724 x_destroy_x_image (ximg
);
7729 fn_g_object_unref (rsvg_handle
);
7730 /* FIXME: Use error->message so the user knows what is the actual
7731 problem with the image. */
7732 image_error ("Error parsing SVG image `%s'", img
->spec
, Qnil
);
7733 fn_g_error_free (error
);
7737 #endif /* defined (HAVE_RSVG) */
7742 /***********************************************************************
7744 ***********************************************************************/
7746 #ifdef HAVE_X_WINDOWS
7747 #define HAVE_GHOSTSCRIPT 1
7748 #endif /* HAVE_X_WINDOWS */
7750 /* The symbol `postscript' identifying images of this type. */
7752 Lisp_Object Qpostscript
;
7754 #ifdef HAVE_GHOSTSCRIPT
7756 static int gs_image_p (Lisp_Object object
);
7757 static int gs_load (struct frame
*f
, struct image
*img
);
7758 static void gs_clear_image (struct frame
*f
, struct image
*img
);
7760 /* Keyword symbols. */
7762 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
7764 /* Indices of image specification fields in gs_format, below. */
7766 enum gs_keyword_index
7784 /* Vector of image_keyword structures describing the format
7785 of valid user-defined image specifications. */
7787 static const struct image_keyword gs_format
[GS_LAST
] =
7789 {":type", IMAGE_SYMBOL_VALUE
, 1},
7790 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
7791 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
7792 {":file", IMAGE_STRING_VALUE
, 1},
7793 {":loader", IMAGE_FUNCTION_VALUE
, 0},
7794 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
7795 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7796 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7797 {":relief", IMAGE_INTEGER_VALUE
, 0},
7798 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7799 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7800 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7801 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7804 /* Structure describing the image type `ghostscript'. */
7806 static struct image_type gs_type
=
7816 /* Free X resources of Ghostscript image IMG which is used on frame F. */
7819 gs_clear_image (struct frame
*f
, struct image
*img
)
7821 /* IMG->data.ptr_val may contain a recorded colormap. */
7822 xfree (img
->data
.ptr_val
);
7823 x_clear_image (f
, img
);
7827 /* Return non-zero if OBJECT is a valid Ghostscript image
7831 gs_image_p (Lisp_Object object
)
7833 struct image_keyword fmt
[GS_LAST
];
7837 memcpy (fmt
, gs_format
, sizeof fmt
);
7839 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
7842 /* Bounding box must be a list or vector containing 4 integers. */
7843 tem
= fmt
[GS_BOUNDING_BOX
].value
;
7846 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
7847 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
7852 else if (VECTORP (tem
))
7854 if (XVECTOR (tem
)->size
!= 4)
7856 for (i
= 0; i
< 4; ++i
)
7857 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
7867 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
7871 gs_load (struct frame
*f
, struct image
*img
)
7874 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
7875 struct gcpro gcpro1
, gcpro2
;
7877 double in_width
, in_height
;
7878 Lisp_Object pixel_colors
= Qnil
;
7880 /* Compute pixel size of pixmap needed from the given size in the
7881 image specification. Sizes in the specification are in pt. 1 pt
7882 = 1/72 in, xdpi and ydpi are stored in the frame's X display
7884 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
7885 in_width
= XFASTINT (pt_width
) / 72.0;
7886 img
->width
= in_width
* FRAME_X_DISPLAY_INFO (f
)->resx
;
7887 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
7888 in_height
= XFASTINT (pt_height
) / 72.0;
7889 img
->height
= in_height
* FRAME_X_DISPLAY_INFO (f
)->resy
;
7891 if (!check_image_size (f
, img
->width
, img
->height
))
7893 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7897 /* Create the pixmap. */
7898 xassert (img
->pixmap
== NO_PIXMAP
);
7900 /* Only W32 version did BLOCK_INPUT here. ++kfs */
7902 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7903 img
->width
, img
->height
,
7904 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
7909 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
7913 /* Call the loader to fill the pixmap. It returns a process object
7914 if successful. We do not record_unwind_protect here because
7915 other places in redisplay like calling window scroll functions
7916 don't either. Let the Lisp loader use `unwind-protect' instead. */
7917 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
7919 sprintf (buffer
, "%lu %lu",
7920 (unsigned long) FRAME_X_WINDOW (f
),
7921 (unsigned long) img
->pixmap
);
7922 window_and_pixmap_id
= build_string (buffer
);
7924 sprintf (buffer
, "%lu %lu",
7925 FRAME_FOREGROUND_PIXEL (f
),
7926 FRAME_BACKGROUND_PIXEL (f
));
7927 pixel_colors
= build_string (buffer
);
7929 XSETFRAME (frame
, f
);
7930 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
7932 loader
= intern ("gs-load-image");
7934 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
7935 make_number (img
->width
),
7936 make_number (img
->height
),
7937 window_and_pixmap_id
,
7940 return PROCESSP (img
->data
.lisp_val
);
7944 /* Kill the Ghostscript process that was started to fill PIXMAP on
7945 frame F. Called from XTread_socket when receiving an event
7946 telling Emacs that Ghostscript has finished drawing. */
7949 x_kill_gs_process (Pixmap pixmap
, struct frame
*f
)
7951 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
7955 /* Find the image containing PIXMAP. */
7956 for (i
= 0; i
< c
->used
; ++i
)
7957 if (c
->images
[i
]->pixmap
== pixmap
)
7960 /* Should someone in between have cleared the image cache, for
7961 instance, give up. */
7965 /* Kill the GS process. We should have found PIXMAP in the image
7966 cache and its image should contain a process object. */
7968 xassert (PROCESSP (img
->data
.lisp_val
));
7969 Fkill_process (img
->data
.lisp_val
, Qnil
);
7970 img
->data
.lisp_val
= Qnil
;
7972 #if defined (HAVE_X_WINDOWS)
7974 /* On displays with a mutable colormap, figure out the colors
7975 allocated for the image by looking at the pixels of an XImage for
7977 class = FRAME_X_VISUAL (f
)->class;
7978 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
7984 /* Try to get an XImage for img->pixmep. */
7985 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
7986 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
7991 /* Initialize the color table. */
7992 init_color_table ();
7994 /* For each pixel of the image, look its color up in the
7995 color table. After having done so, the color table will
7996 contain an entry for each color used by the image. */
7997 for (y
= 0; y
< img
->height
; ++y
)
7998 for (x
= 0; x
< img
->width
; ++x
)
8000 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
8001 lookup_pixel_color (f
, pixel
);
8004 /* Record colors in the image. Free color table and XImage. */
8005 #ifdef COLOR_TABLE_SUPPORT
8006 img
->colors
= colors_in_color_table (&img
->ncolors
);
8007 free_color_table ();
8009 XDestroyImage (ximg
);
8011 #if 0 /* This doesn't seem to be the case. If we free the colors
8012 here, we get a BadAccess later in x_clear_image when
8013 freeing the colors. */
8014 /* We have allocated colors once, but Ghostscript has also
8015 allocated colors on behalf of us. So, to get the
8016 reference counts right, free them once. */
8018 x_free_colors (f
, img
->colors
, img
->ncolors
);
8022 image_error ("Cannot get X image of `%s'; colors will not be freed",
8027 #endif /* HAVE_X_WINDOWS */
8029 /* Now that we have the pixmap, compute mask and transform the
8030 image if requested. */
8032 postprocess_image (f
, img
);
8036 #endif /* HAVE_GHOSTSCRIPT */
8039 /***********************************************************************
8041 ***********************************************************************/
8045 DEFUN ("imagep", Fimagep
, Simagep
, 1, 1, 0,
8046 doc
: /* Value is non-nil if SPEC is a valid image specification. */)
8049 return valid_image_p (spec
) ? Qt
: Qnil
;
8053 DEFUN ("lookup-image", Flookup_image
, Slookup_image
, 1, 1, 0, "")
8058 if (valid_image_p (spec
))
8059 id
= lookup_image (SELECTED_FRAME (), spec
);
8062 return make_number (id
);
8065 #endif /* GLYPH_DEBUG != 0 */
8068 /***********************************************************************
8070 ***********************************************************************/
8073 /* Image types that rely on external libraries are loaded dynamically
8074 if the library is available. */
8075 #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8076 define_image_type (image_type, init_lib_fn (libraries))
8078 #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8079 define_image_type (image_type, 1)
8080 #endif /* HAVE_NTGUI */
8082 DEFUN ("init-image-library", Finit_image_library
, Sinit_image_library
, 2, 2, 0,
8083 doc
: /* Initialize image library implementing image type TYPE.
8084 Return non-nil if TYPE is a supported image type.
8086 Image types pbm and xbm are prebuilt; other types are loaded here.
8087 Libraries to load are specified in alist LIBRARIES (usually, the value
8088 of `image-library-alist', which see). */)
8089 (Lisp_Object type
, Lisp_Object libraries
)
8093 /* Don't try to reload the library. */
8094 tested
= Fassq (type
, Vimage_type_cache
);
8096 return XCDR (tested
);
8098 #if defined (HAVE_XPM) || defined (HAVE_NS)
8099 if (EQ (type
, Qxpm
))
8100 return CHECK_LIB_AVAILABLE (&xpm_type
, init_xpm_functions
, libraries
);
8103 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8104 if (EQ (type
, Qjpeg
))
8105 return CHECK_LIB_AVAILABLE (&jpeg_type
, init_jpeg_functions
, libraries
);
8108 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8109 if (EQ (type
, Qtiff
))
8110 return CHECK_LIB_AVAILABLE (&tiff_type
, init_tiff_functions
, libraries
);
8113 #if defined (HAVE_GIF) || defined (HAVE_NS)
8114 if (EQ (type
, Qgif
))
8115 return CHECK_LIB_AVAILABLE (&gif_type
, init_gif_functions
, libraries
);
8118 #if defined (HAVE_PNG) || defined (HAVE_NS)
8119 if (EQ (type
, Qpng
))
8120 return CHECK_LIB_AVAILABLE (&png_type
, init_png_functions
, libraries
);
8123 #if defined (HAVE_RSVG)
8124 if (EQ (type
, Qsvg
))
8125 return CHECK_LIB_AVAILABLE (&svg_type
, init_svg_functions
, libraries
);
8128 #ifdef HAVE_GHOSTSCRIPT
8129 if (EQ (type
, Qpostscript
))
8130 return CHECK_LIB_AVAILABLE (&gs_type
, init_gs_functions
, libraries
);
8133 /* If the type is not recognized, avoid testing it ever again. */
8134 CACHE_IMAGE_TYPE (type
, Qnil
);
8139 syms_of_image (void)
8141 extern Lisp_Object Qrisky_local_variable
; /* Syms_of_xdisp has already run. */
8143 /* Initialize this only once, since that's what we do with Vimage_types
8144 and they are supposed to be in sync. Initializing here gives correct
8145 operation on GNU/Linux of calling dump-emacs after loading some images. */
8148 /* Must be defined now becase we're going to update it below, while
8149 defining the supported image types. */
8150 DEFVAR_LISP ("image-types", &Vimage_types
,
8151 doc
: /* List of potentially supported image types.
8152 Each element of the list is a symbol for an image type, like 'jpeg or 'png.
8153 To check whether it is really supported, use `image-type-available-p'. */);
8154 Vimage_types
= Qnil
;
8156 DEFVAR_LISP ("image-library-alist", &Vimage_library_alist
,
8157 doc
: /* Alist of image types vs external libraries needed to display them.
8159 Each element is a list (IMAGE-TYPE LIBRARY...), where the car is a symbol
8160 representing a supported image type, and the rest are strings giving
8161 alternate filenames for the corresponding external libraries.
8163 Emacs tries to load the libraries in the order they appear on the
8164 list; if none is loaded, the running session of Emacs won't
8165 support the image type. Types 'pbm and 'xbm don't need to be
8166 listed; they are always supported. */);
8167 Vimage_library_alist
= Qnil
;
8168 Fput (intern_c_string ("image-library-alist"), Qrisky_local_variable
, Qt
);
8170 DEFVAR_LISP ("max-image-size", &Vmax_image_size
,
8171 doc
: /* Maximum size of images.
8172 Emacs will not load an image into memory if its pixel width or
8173 pixel height exceeds this limit.
8175 If the value is an integer, it directly specifies the maximum
8176 image height and width, measured in pixels. If it is a floating
8177 point number, it specifies the maximum image height and width
8178 as a ratio to the frame height and width. If the value is
8179 non-numeric, there is no explicit limit on the size of images. */);
8180 Vmax_image_size
= make_float (MAX_IMAGE_SIZE
);
8182 Vimage_type_cache
= Qnil
;
8183 staticpro (&Vimage_type_cache
);
8185 Qpbm
= intern_c_string ("pbm");
8187 ADD_IMAGE_TYPE (Qpbm
);
8189 Qxbm
= intern_c_string ("xbm");
8191 ADD_IMAGE_TYPE (Qxbm
);
8193 define_image_type (&xbm_type
, 1);
8194 define_image_type (&pbm_type
, 1);
8196 Qcount
= intern_c_string ("count");
8197 staticpro (&Qcount
);
8198 Qextension_data
= intern_c_string ("extension-data");
8199 staticpro (&Qextension_data
);
8201 QCascent
= intern_c_string (":ascent");
8202 staticpro (&QCascent
);
8203 QCmargin
= intern_c_string (":margin");
8204 staticpro (&QCmargin
);
8205 QCrelief
= intern_c_string (":relief");
8206 staticpro (&QCrelief
);
8207 QCconversion
= intern_c_string (":conversion");
8208 staticpro (&QCconversion
);
8209 QCcolor_symbols
= intern_c_string (":color-symbols");
8210 staticpro (&QCcolor_symbols
);
8211 QCheuristic_mask
= intern_c_string (":heuristic-mask");
8212 staticpro (&QCheuristic_mask
);
8213 QCindex
= intern_c_string (":index");
8214 staticpro (&QCindex
);
8215 QCmatrix
= intern_c_string (":matrix");
8216 staticpro (&QCmatrix
);
8217 QCcolor_adjustment
= intern_c_string (":color-adjustment");
8218 staticpro (&QCcolor_adjustment
);
8219 QCmask
= intern_c_string (":mask");
8220 staticpro (&QCmask
);
8222 Qlaplace
= intern_c_string ("laplace");
8223 staticpro (&Qlaplace
);
8224 Qemboss
= intern_c_string ("emboss");
8225 staticpro (&Qemboss
);
8226 Qedge_detection
= intern_c_string ("edge-detection");
8227 staticpro (&Qedge_detection
);
8228 Qheuristic
= intern_c_string ("heuristic");
8229 staticpro (&Qheuristic
);
8231 Qpostscript
= intern_c_string ("postscript");
8232 staticpro (&Qpostscript
);
8233 #ifdef HAVE_GHOSTSCRIPT
8234 ADD_IMAGE_TYPE (Qpostscript
);
8235 QCloader
= intern_c_string (":loader");
8236 staticpro (&QCloader
);
8237 QCbounding_box
= intern_c_string (":bounding-box");
8238 staticpro (&QCbounding_box
);
8239 QCpt_width
= intern_c_string (":pt-width");
8240 staticpro (&QCpt_width
);
8241 QCpt_height
= intern_c_string (":pt-height");
8242 staticpro (&QCpt_height
);
8243 #endif /* HAVE_GHOSTSCRIPT */
8245 #if defined (HAVE_XPM) || defined (HAVE_NS)
8246 Qxpm
= intern_c_string ("xpm");
8248 ADD_IMAGE_TYPE (Qxpm
);
8251 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8252 Qjpeg
= intern_c_string ("jpeg");
8254 ADD_IMAGE_TYPE (Qjpeg
);
8257 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8258 Qtiff
= intern_c_string ("tiff");
8260 ADD_IMAGE_TYPE (Qtiff
);
8263 #if defined (HAVE_GIF) || defined (HAVE_NS)
8264 Qgif
= intern_c_string ("gif");
8266 ADD_IMAGE_TYPE (Qgif
);
8269 #if defined (HAVE_PNG) || defined (HAVE_NS)
8270 Qpng
= intern_c_string ("png");
8272 ADD_IMAGE_TYPE (Qpng
);
8275 #if defined (HAVE_RSVG)
8276 Qsvg
= intern_c_string ("svg");
8278 ADD_IMAGE_TYPE (Qsvg
);
8280 /* Other libraries used directly by svg code. */
8281 Qgdk_pixbuf
= intern_c_string ("gdk-pixbuf");
8282 staticpro (&Qgdk_pixbuf
);
8283 Qglib
= intern_c_string ("glib");
8285 Qgobject
= intern_c_string ("gobject");
8286 staticpro (&Qgobject
);
8287 #endif /* HAVE_NTGUI */
8288 #endif /* HAVE_RSVG */
8290 defsubr (&Sinit_image_library
);
8291 defsubr (&Sclear_image_cache
);
8292 defsubr (&Simage_flush
);
8293 defsubr (&Simage_size
);
8294 defsubr (&Simage_mask_p
);
8295 defsubr (&Simage_metadata
);
8299 defsubr (&Slookup_image
);
8302 DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images
,
8303 doc
: /* Non-nil means always draw a cross over disabled images.
8304 Disabled images are those having a `:conversion disabled' property.
8305 A cross is always drawn on black & white displays. */);
8306 cross_disabled_images
= 0;
8308 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
8309 doc
: /* List of directories to search for window system bitmap files. */);
8310 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
8312 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
8313 doc
: /* Maximum time after which images are removed from the cache.
8314 When an image has not been displayed this many seconds, Emacs
8315 automatically removes it from the image cache. If the cache contains
8316 a large number of images, the actual eviction time may be shorter.
8317 The value can also be nil, meaning the cache is never cleared.
8319 The function `clear-image-cache' disregards this variable. */);
8320 Vimage_cache_eviction_delay
= make_number (300);
8328 /* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9
8329 (do not change this comment) */