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 (spec
, pixels
, frame
)
930 Lisp_Object spec
, pixels
, frame
;
935 if (valid_image_p (spec
))
937 struct frame
*f
= check_x_frame (frame
);
938 int id
= lookup_image (f
, spec
);
939 struct image
*img
= IMAGE_FROM_ID (f
, id
);
940 int width
= img
->width
+ 2 * img
->hmargin
;
941 int height
= img
->height
+ 2 * img
->vmargin
;
944 size
= Fcons (make_float ((double) width
/ FRAME_COLUMN_WIDTH (f
)),
945 make_float ((double) height
/ FRAME_LINE_HEIGHT (f
)));
947 size
= Fcons (make_number (width
), make_number (height
));
950 error ("Invalid image specification");
956 DEFUN ("image-mask-p", Fimage_mask_p
, Simage_mask_p
, 1, 2, 0,
957 doc
: /* Return t if image SPEC has a mask bitmap.
958 FRAME is the frame on which the image will be displayed. FRAME nil
959 or omitted means use the selected frame. */)
961 Lisp_Object spec
, frame
;
966 if (valid_image_p (spec
))
968 struct frame
*f
= check_x_frame (frame
);
969 int id
= lookup_image (f
, spec
);
970 struct image
*img
= IMAGE_FROM_ID (f
, id
);
975 error ("Invalid image specification");
980 DEFUN ("image-metadata", Fimage_metadata
, Simage_metadata
, 1, 2, 0,
981 doc
: /* Return metadata for image SPEC.
982 FRAME is the frame on which the image will be displayed. FRAME nil
983 or omitted means use the selected frame. */)
985 Lisp_Object spec
, frame
;
990 if (valid_image_p (spec
))
992 struct frame
*f
= check_x_frame (frame
);
993 int id
= lookup_image (f
, spec
);
994 struct image
*img
= IMAGE_FROM_ID (f
, id
);
995 ext
= img
->data
.lisp_val
;
1002 /***********************************************************************
1003 Image type independent image structures
1004 ***********************************************************************/
1006 static struct image
*make_image (Lisp_Object spec
, unsigned hash
);
1007 static void free_image (struct frame
*f
, struct image
*img
);
1008 static int check_image_size (struct frame
*f
, int width
, int height
);
1010 #define MAX_IMAGE_SIZE 6.0
1011 Lisp_Object Vmax_image_size
;
1013 /* Allocate and return a new image structure for image specification
1014 SPEC. SPEC has a hash value of HASH. */
1016 static struct image
*
1017 make_image (Lisp_Object spec
, unsigned int hash
)
1019 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
1020 Lisp_Object file
= image_spec_value (spec
, QCfile
, NULL
);
1022 xassert (valid_image_p (spec
));
1023 memset (img
, 0, sizeof *img
);
1024 img
->dependencies
= NILP (file
) ? Qnil
: list1 (file
);
1025 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
1026 xassert (img
->type
!= NULL
);
1028 img
->data
.lisp_val
= Qnil
;
1029 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
1031 img
->corners
[BOT_CORNER
] = -1; /* Full image */
1036 /* Free image IMG which was used on frame F, including its resources. */
1039 free_image (struct frame
*f
, struct image
*img
)
1043 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1045 /* Remove IMG from the hash table of its cache. */
1047 img
->prev
->next
= img
->next
;
1049 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
1052 img
->next
->prev
= img
->prev
;
1054 c
->images
[img
->id
] = NULL
;
1056 /* Free resources, then free IMG. */
1057 img
->type
->free (f
, img
);
1062 /* Return 1 if the given widths and heights are valid for display;
1063 otherwise, return 0. */
1066 check_image_size (struct frame
*f
, int width
, int height
)
1070 if (width
<= 0 || height
<= 0)
1073 if (INTEGERP (Vmax_image_size
))
1074 w
= h
= XINT (Vmax_image_size
);
1075 else if (FLOATP (Vmax_image_size
))
1079 w
= FRAME_PIXEL_WIDTH (f
);
1080 h
= FRAME_PIXEL_HEIGHT (f
);
1083 w
= h
= 1024; /* Arbitrary size for unknown frame. */
1084 w
= (int) (XFLOAT_DATA (Vmax_image_size
) * w
);
1085 h
= (int) (XFLOAT_DATA (Vmax_image_size
) * h
);
1090 return (width
<= w
&& height
<= h
);
1093 /* Prepare image IMG for display on frame F. Must be called before
1094 drawing an image. */
1097 prepare_image_for_display (struct frame
*f
, struct image
*img
)
1101 /* We're about to display IMG, so set its timestamp to `now'. */
1103 img
->timestamp
= EMACS_SECS (t
);
1105 /* If IMG doesn't have a pixmap yet, load it now, using the image
1106 type dependent loader function. */
1107 if (img
->pixmap
== NO_PIXMAP
&& !img
->load_failed_p
)
1108 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
1113 /* Value is the number of pixels for the ascent of image IMG when
1114 drawn in face FACE. */
1117 image_ascent (struct image
*img
, struct face
*face
, struct glyph_slice
*slice
)
1122 if (slice
->height
== img
->height
)
1123 height
= img
->height
+ img
->vmargin
;
1124 else if (slice
->y
== 0)
1125 height
= slice
->height
+ img
->vmargin
;
1127 height
= slice
->height
;
1129 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
1134 /* W32 specific version. Why?. ++kfs */
1135 ascent
= height
/ 2 - (FONT_DESCENT (face
->font
)
1136 - FONT_BASE (face
->font
)) / 2;
1138 /* This expression is arranged so that if the image can't be
1139 exactly centered, it will be moved slightly up. This is
1140 because a typical font is `top-heavy' (due to the presence
1141 uppercase letters), so the image placement should err towards
1142 being top-heavy too. It also just generally looks better. */
1143 ascent
= (height
+ FONT_BASE(face
->font
)
1144 - FONT_DESCENT(face
->font
) + 1) / 2;
1145 #endif /* HAVE_NTGUI */
1148 ascent
= height
/ 2;
1151 ascent
= (int) (height
* img
->ascent
/ 100.0);
1157 /* Image background colors. */
1159 /* Find the "best" corner color of a bitmap.
1160 On W32, XIMG is assumed to a device context with the bitmap selected. */
1162 static RGB_PIXEL_COLOR
1163 four_corners_best (XImagePtr_or_DC ximg
, int *corners
,
1164 unsigned long width
, unsigned long height
)
1166 RGB_PIXEL_COLOR corner_pixels
[4], best
;
1169 if (corners
&& corners
[BOT_CORNER
] >= 0)
1171 /* Get the colors at the corner_pixels of ximg. */
1172 corner_pixels
[0] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[TOP_CORNER
]);
1173 corner_pixels
[1] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[TOP_CORNER
]);
1174 corner_pixels
[2] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[BOT_CORNER
] - 1);
1175 corner_pixels
[3] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[BOT_CORNER
] - 1);
1179 /* Get the colors at the corner_pixels of ximg. */
1180 corner_pixels
[0] = GET_PIXEL (ximg
, 0, 0);
1181 corner_pixels
[1] = GET_PIXEL (ximg
, width
- 1, 0);
1182 corner_pixels
[2] = GET_PIXEL (ximg
, width
- 1, height
- 1);
1183 corner_pixels
[3] = GET_PIXEL (ximg
, 0, height
- 1);
1185 /* Choose the most frequently found color as background. */
1186 for (i
= best_count
= 0; i
< 4; ++i
)
1190 for (j
= n
= 0; j
< 4; ++j
)
1191 if (corner_pixels
[i
] == corner_pixels
[j
])
1195 best
= corner_pixels
[i
], best_count
= n
;
1201 /* Portability macros */
1205 #define Destroy_Image(img_dc, prev) \
1206 do { SelectObject (img_dc, prev); DeleteDC (img_dc); } while (0)
1208 #define Free_Pixmap(display, pixmap) \
1209 DeleteObject (pixmap)
1211 #elif defined (HAVE_NS)
1213 #define Destroy_Image(ximg, dummy) \
1214 ns_release_object (ximg)
1216 #define Free_Pixmap(display, pixmap) \
1217 ns_release_object (pixmap)
1221 #define Destroy_Image(ximg, dummy) \
1222 XDestroyImage (ximg)
1224 #define Free_Pixmap(display, pixmap) \
1225 XFreePixmap (display, pixmap)
1227 #endif /* !HAVE_NTGUI && !HAVE_NS */
1230 /* Return the `background' field of IMG. If IMG doesn't have one yet,
1231 it is guessed heuristically. If non-zero, XIMG is an existing
1232 XImage object (or device context with the image selected on W32) to
1233 use for the heuristic. */
1236 image_background (struct image
*img
, struct frame
*f
, XImagePtr_or_DC ximg
)
1238 if (! img
->background_valid
)
1239 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1241 int free_ximg
= !ximg
;
1244 #endif /* HAVE_NTGUI */
1249 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
1250 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
1252 HDC frame_dc
= get_frame_dc (f
);
1253 ximg
= CreateCompatibleDC (frame_dc
);
1254 release_frame_dc (f
, frame_dc
);
1255 prev
= SelectObject (ximg
, img
->pixmap
);
1256 #endif /* !HAVE_NTGUI */
1259 img
->background
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
1262 Destroy_Image (ximg
, prev
);
1264 img
->background_valid
= 1;
1267 return img
->background
;
1270 /* Return the `background_transparent' field of IMG. If IMG doesn't
1271 have one yet, it is guessed heuristically. If non-zero, MASK is an
1272 existing XImage object to use for the heuristic. */
1275 image_background_transparent (struct image
*img
, struct frame
*f
, XImagePtr_or_DC mask
)
1277 if (! img
->background_transparent_valid
)
1278 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1282 int free_mask
= !mask
;
1285 #endif /* HAVE_NTGUI */
1290 mask
= XGetImage (FRAME_X_DISPLAY (f
), img
->mask
,
1291 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
1293 HDC frame_dc
= get_frame_dc (f
);
1294 mask
= CreateCompatibleDC (frame_dc
);
1295 release_frame_dc (f
, frame_dc
);
1296 prev
= SelectObject (mask
, img
->mask
);
1297 #endif /* HAVE_NTGUI */
1300 img
->background_transparent
1301 = (four_corners_best (mask
, img
->corners
, img
->width
, img
->height
) == PIX_MASK_RETAIN
);
1304 Destroy_Image (mask
, prev
);
1307 img
->background_transparent
= 0;
1309 img
->background_transparent_valid
= 1;
1312 return img
->background_transparent
;
1316 /***********************************************************************
1317 Helper functions for X image types
1318 ***********************************************************************/
1320 static void x_clear_image_1 (struct frame
*, struct image
*, int,
1322 static void x_clear_image (struct frame
*f
, struct image
*img
);
1323 static unsigned long x_alloc_image_color (struct frame
*f
,
1325 Lisp_Object color_name
,
1326 unsigned long dflt
);
1329 /* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
1330 free the pixmap if any. MASK_P non-zero means clear the mask
1331 pixmap if any. COLORS_P non-zero means free colors allocated for
1332 the image, if any. */
1335 x_clear_image_1 (struct frame
*f
, struct image
*img
, int pixmap_p
, int mask_p
,
1338 if (pixmap_p
&& img
->pixmap
)
1340 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
1341 img
->pixmap
= NO_PIXMAP
;
1342 /* NOTE (HAVE_NS): background color is NOT an indexed color! */
1343 img
->background_valid
= 0;
1346 if (mask_p
&& img
->mask
)
1348 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
1349 img
->mask
= NO_PIXMAP
;
1350 img
->background_transparent_valid
= 0;
1353 if (colors_p
&& img
->ncolors
)
1355 /* W32_TODO: color table support. */
1356 #ifdef HAVE_X_WINDOWS
1357 x_free_colors (f
, img
->colors
, img
->ncolors
);
1358 #endif /* HAVE_X_WINDOWS */
1359 xfree (img
->colors
);
1366 /* Free X resources of image IMG which is used on frame F. */
1369 x_clear_image (struct frame
*f
, struct image
*img
)
1372 x_clear_image_1 (f
, img
, 1, 1, 1);
1377 /* Allocate color COLOR_NAME for image IMG on frame F. If color
1378 cannot be allocated, use DFLT. Add a newly allocated color to
1379 IMG->colors, so that it can be freed again. Value is the pixel
1382 static unsigned long
1383 x_alloc_image_color (struct frame
*f
, struct image
*img
, Lisp_Object color_name
,
1387 unsigned long result
;
1389 xassert (STRINGP (color_name
));
1391 if (x_defined_color (f
, SDATA (color_name
), &color
, 1))
1393 /* This isn't called frequently so we get away with simply
1394 reallocating the color vector to the needed size, here. */
1397 (unsigned long *) xrealloc (img
->colors
,
1398 img
->ncolors
* sizeof *img
->colors
);
1399 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
1400 result
= color
.pixel
;
1410 /***********************************************************************
1412 ***********************************************************************/
1414 static struct image
*search_image_cache (struct frame
*, Lisp_Object
, unsigned);
1415 static void cache_image (struct frame
*f
, struct image
*img
);
1416 static void postprocess_image (struct frame
*, struct image
*);
1418 /* Return a new, initialized image cache that is allocated from the
1419 heap. Call free_image_cache to free an image cache. */
1421 struct image_cache
*
1422 make_image_cache (void)
1424 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
1427 memset (c
, 0, sizeof *c
);
1429 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
1430 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
1431 c
->buckets
= (struct image
**) xmalloc (size
);
1432 memset (c
->buckets
, 0, size
);
1437 /* Find an image matching SPEC in the cache, and return it. If no
1438 image is found, return NULL. */
1439 static struct image
*
1440 search_image_cache (struct frame
*f
, Lisp_Object spec
, unsigned int hash
)
1443 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1444 int i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1446 if (!c
) return NULL
;
1448 /* If the image spec does not specify a background color, the cached
1449 image must have the same background color as the current frame.
1450 The foreground color must also match, for the sake of monochrome
1453 In fact, we could ignore the foreground color matching condition
1454 for color images, or if the image spec specifies :foreground;
1455 similarly we could ignore the background color matching condition
1456 for formats that don't use transparency (such as jpeg), or if the
1457 image spec specifies :background. However, the extra memory
1458 usage is probably negligible in practice, so we don't bother. */
1460 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
1461 if (img
->hash
== hash
1462 && !NILP (Fequal (img
->spec
, spec
))
1463 && img
->frame_foreground
== FRAME_FOREGROUND_PIXEL (f
)
1464 && img
->frame_background
== FRAME_BACKGROUND_PIXEL (f
))
1470 /* Search frame F for an image with spec SPEC, and free it. */
1473 uncache_image (struct frame
*f
, Lisp_Object spec
)
1475 struct image
*img
= search_image_cache (f
, spec
, sxhash (spec
, 0));
1477 free_image (f
, img
);
1481 /* Free image cache of frame F. Be aware that X frames share images
1485 free_image_cache (struct frame
*f
)
1487 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1492 /* Cache should not be referenced by any frame when freed. */
1493 xassert (c
->refcount
== 0);
1495 for (i
= 0; i
< c
->used
; ++i
)
1496 free_image (f
, c
->images
[i
]);
1500 FRAME_IMAGE_CACHE (f
) = NULL
;
1505 /* Clear image cache of frame F. FILTER=t means free all images.
1506 FILTER=nil means clear only images that haven't been
1507 displayed for some time.
1508 Else, only free the images which have FILTER in their `dependencies'.
1509 Should be called from time to time to reduce the number of loaded images.
1510 If image-cache-eviction-delay is non-nil, this frees images in the cache
1511 which weren't displayed for at least that many seconds. */
1514 clear_image_cache (struct frame
*f
, Lisp_Object filter
)
1516 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1522 /* Block input so that we won't be interrupted by a SIGIO
1523 while being in an inconsistent state. */
1528 /* Filter image cache. */
1529 for (i
= 0; i
< c
->used
; ++i
)
1531 struct image
*img
= c
->images
[i
];
1532 if (img
&& (EQ (Qt
, filter
)
1533 || !NILP (Fmember (filter
, img
->dependencies
))))
1535 free_image (f
, img
);
1540 else if (INTEGERP (Vimage_cache_eviction_delay
))
1542 /* Free cache based on timestamp. */
1545 int delay
, nimages
= 0;
1547 for (i
= 0; i
< c
->used
; ++i
)
1551 /* If the number of cached images has grown unusually large,
1552 decrease the cache eviction delay (Bug#6230). */
1553 delay
= XFASTINT (Vimage_cache_eviction_delay
);
1555 delay
= max (1, 1600 * delay
/ (nimages
*nimages
));
1558 old
= EMACS_SECS (t
) - delay
;
1560 for (i
= 0; i
< c
->used
; ++i
)
1562 struct image
*img
= c
->images
[i
];
1563 if (img
&& img
->timestamp
< old
)
1565 free_image (f
, img
);
1571 /* We may be clearing the image cache because, for example,
1572 Emacs was iconified for a longer period of time. In that
1573 case, current matrices may still contain references to
1574 images freed above. So, clear these matrices. */
1577 Lisp_Object tail
, frame
;
1579 FOR_EACH_FRAME (tail
, frame
)
1581 struct frame
*f
= XFRAME (frame
);
1582 if (FRAME_IMAGE_CACHE (f
) == c
)
1583 clear_current_matrices (f
);
1586 ++windows_or_buffers_changed
;
1594 clear_image_caches (Lisp_Object filter
)
1596 /* FIXME: We want to do
1597 * struct terminal *t;
1598 * for (t = terminal_list; t; t = t->next_terminal)
1599 * clear_image_cache (t, filter); */
1600 Lisp_Object tail
, frame
;
1601 FOR_EACH_FRAME (tail
, frame
)
1602 if (FRAME_WINDOW_P (XFRAME (frame
)))
1603 clear_image_cache (XFRAME (frame
), filter
);
1606 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
1608 doc
: /* Clear the image cache.
1609 FILTER nil or a frame means clear all images in the selected frame.
1610 FILTER t means clear the image caches of all frames.
1611 Anything else, means only clear those images which refer to FILTER,
1612 which is then usually a filename. */)
1616 if (!(EQ (filter
, Qnil
) || FRAMEP (filter
)))
1617 clear_image_caches (filter
);
1619 clear_image_cache (check_x_frame (filter
), Qt
);
1625 DEFUN ("image-flush", Fimage_flush
, Simage_flush
,
1627 doc
: /* Fush the image with specification SPEC on frame FRAME.
1628 This removes the image from the Emacs image cache. If SPEC specifies
1629 an image file, the next redisplay of this image will read from the
1630 current contents of that file.
1632 FRAME nil or omitted means use the selected frame.
1633 FRAME t means refresh the image on all frames. */)
1635 Lisp_Object spec
, frame
;
1637 if (!valid_image_p (spec
))
1638 error ("Invalid image specification");
1643 FOR_EACH_FRAME (tail
, frame
)
1645 struct frame
*f
= XFRAME (frame
);
1646 if (FRAME_WINDOW_P (f
))
1647 uncache_image (f
, spec
);
1651 uncache_image (check_x_frame (frame
), spec
);
1657 /* Compute masks and transform image IMG on frame F, as specified
1658 by the image's specification, */
1661 postprocess_image (struct frame
*f
, struct image
*img
)
1663 /* Manipulation of the image's mask. */
1666 Lisp_Object conversion
, spec
;
1671 /* `:heuristic-mask t'
1673 means build a mask heuristically.
1674 `:heuristic-mask (R G B)'
1675 `:mask (heuristic (R G B))'
1676 means build a mask from color (R G B) in the
1679 means remove a mask, if any. */
1681 mask
= image_spec_value (spec
, QCheuristic_mask
, NULL
);
1683 x_build_heuristic_mask (f
, img
, mask
);
1688 mask
= image_spec_value (spec
, QCmask
, &found_p
);
1690 if (EQ (mask
, Qheuristic
))
1691 x_build_heuristic_mask (f
, img
, Qt
);
1692 else if (CONSP (mask
)
1693 && EQ (XCAR (mask
), Qheuristic
))
1695 if (CONSP (XCDR (mask
)))
1696 x_build_heuristic_mask (f
, img
, XCAR (XCDR (mask
)));
1698 x_build_heuristic_mask (f
, img
, XCDR (mask
));
1700 else if (NILP (mask
) && found_p
&& img
->mask
)
1702 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
1703 img
->mask
= NO_PIXMAP
;
1708 /* Should we apply an image transformation algorithm? */
1709 conversion
= image_spec_value (spec
, QCconversion
, NULL
);
1710 if (EQ (conversion
, Qdisabled
))
1711 x_disable_image (f
, img
);
1712 else if (EQ (conversion
, Qlaplace
))
1714 else if (EQ (conversion
, Qemboss
))
1716 else if (CONSP (conversion
)
1717 && EQ (XCAR (conversion
), Qedge_detection
))
1720 tem
= XCDR (conversion
);
1722 x_edge_detection (f
, img
,
1723 Fplist_get (tem
, QCmatrix
),
1724 Fplist_get (tem
, QCcolor_adjustment
));
1730 /* Return the id of image with Lisp specification SPEC on frame F.
1731 SPEC must be a valid Lisp image specification (see valid_image_p). */
1734 lookup_image (struct frame
*f
, Lisp_Object spec
)
1736 struct image_cache
*c
;
1739 struct gcpro gcpro1
;
1742 /* F must be a window-system frame, and SPEC must be a valid image
1744 xassert (FRAME_WINDOW_P (f
));
1745 xassert (valid_image_p (spec
));
1747 c
= FRAME_IMAGE_CACHE (f
);
1751 /* Look up SPEC in the hash table of the image cache. */
1752 hash
= sxhash (spec
, 0);
1753 img
= search_image_cache (f
, spec
, hash
);
1754 if (img
&& img
->load_failed_p
)
1756 free_image (f
, img
);
1760 /* If not found, create a new image and cache it. */
1763 extern Lisp_Object Qpostscript
;
1766 img
= make_image (spec
, hash
);
1767 cache_image (f
, img
);
1768 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
1769 img
->frame_foreground
= FRAME_FOREGROUND_PIXEL (f
);
1770 img
->frame_background
= FRAME_BACKGROUND_PIXEL (f
);
1772 /* If we can't load the image, and we don't have a width and
1773 height, use some arbitrary width and height so that we can
1774 draw a rectangle for it. */
1775 if (img
->load_failed_p
)
1779 value
= image_spec_value (spec
, QCwidth
, NULL
);
1780 img
->width
= (INTEGERP (value
)
1781 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
1782 value
= image_spec_value (spec
, QCheight
, NULL
);
1783 img
->height
= (INTEGERP (value
)
1784 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
1788 /* Handle image type independent image attributes
1789 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
1790 `:background COLOR'. */
1791 Lisp_Object ascent
, margin
, relief
, bg
;
1793 ascent
= image_spec_value (spec
, QCascent
, NULL
);
1794 if (INTEGERP (ascent
))
1795 img
->ascent
= XFASTINT (ascent
);
1796 else if (EQ (ascent
, Qcenter
))
1797 img
->ascent
= CENTERED_IMAGE_ASCENT
;
1799 margin
= image_spec_value (spec
, QCmargin
, NULL
);
1800 if (INTEGERP (margin
) && XINT (margin
) >= 0)
1801 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
1802 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
1803 && INTEGERP (XCDR (margin
)))
1805 if (XINT (XCAR (margin
)) > 0)
1806 img
->hmargin
= XFASTINT (XCAR (margin
));
1807 if (XINT (XCDR (margin
)) > 0)
1808 img
->vmargin
= XFASTINT (XCDR (margin
));
1811 relief
= image_spec_value (spec
, QCrelief
, NULL
);
1812 if (INTEGERP (relief
))
1814 img
->relief
= XINT (relief
);
1815 img
->hmargin
+= eabs (img
->relief
);
1816 img
->vmargin
+= eabs (img
->relief
);
1819 if (! img
->background_valid
)
1821 bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
1825 = x_alloc_image_color (f
, img
, bg
,
1826 FRAME_BACKGROUND_PIXEL (f
));
1827 img
->background_valid
= 1;
1831 /* Do image transformations and compute masks, unless we
1832 don't have the image yet. */
1833 if (!EQ (*img
->type
->type
, Qpostscript
))
1834 postprocess_image (f
, img
);
1840 /* We're using IMG, so set its timestamp to `now'. */
1841 EMACS_GET_TIME (now
);
1842 img
->timestamp
= EMACS_SECS (now
);
1846 /* Value is the image id. */
1851 /* Cache image IMG in the image cache of frame F. */
1854 cache_image (struct frame
*f
, struct image
*img
)
1856 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1859 /* Find a free slot in c->images. */
1860 for (i
= 0; i
< c
->used
; ++i
)
1861 if (c
->images
[i
] == NULL
)
1864 /* If no free slot found, maybe enlarge c->images. */
1865 if (i
== c
->used
&& c
->used
== c
->size
)
1868 c
->images
= (struct image
**) xrealloc (c
->images
,
1869 c
->size
* sizeof *c
->images
);
1872 /* Add IMG to c->images, and assign IMG an id. */
1878 /* Add IMG to the cache's hash table. */
1879 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1880 img
->next
= c
->buckets
[i
];
1882 img
->next
->prev
= img
;
1884 c
->buckets
[i
] = img
;
1888 /* Call FN on every image in the image cache of frame F. Used to mark
1889 Lisp Objects in the image cache. */
1891 /* Mark Lisp objects in image IMG. */
1894 mark_image (struct image
*img
)
1896 mark_object (img
->spec
);
1897 mark_object (img
->dependencies
);
1899 if (!NILP (img
->data
.lisp_val
))
1900 mark_object (img
->data
.lisp_val
);
1905 mark_image_cache (struct image_cache
*c
)
1910 for (i
= 0; i
< c
->used
; ++i
)
1912 mark_image (c
->images
[i
]);
1918 /***********************************************************************
1919 X / NS / W32 support code
1920 ***********************************************************************/
1924 /* Macro for defining functions that will be loaded from image DLLs. */
1925 #define DEF_IMGLIB_FN(func) int (FAR CDECL *fn_##func)()
1927 /* Macro for loading those image functions from the library. */
1928 #define LOAD_IMGLIB_FN(lib,func) { \
1929 fn_##func = (void *) GetProcAddress (lib, #func); \
1930 if (!fn_##func) return 0; \
1933 /* Load a DLL implementing an image type.
1934 The `image-library-alist' variable associates a symbol,
1935 identifying an image type, to a list of possible filenames.
1936 The function returns NULL if no library could be loaded for
1937 the given image type, or if the library was previously loaded;
1938 else the handle of the DLL. */
1940 w32_delayed_load (Lisp_Object libraries
, Lisp_Object type
)
1942 HMODULE library
= NULL
;
1944 if (CONSP (libraries
) && NILP (Fassq (type
, Vimage_type_cache
)))
1946 Lisp_Object dlls
= Fassq (type
, libraries
);
1949 for (dlls
= XCDR (dlls
); CONSP (dlls
); dlls
= XCDR (dlls
))
1951 CHECK_STRING_CAR (dlls
);
1952 if (library
= LoadLibrary (SDATA (XCAR (dlls
))))
1960 #endif /* HAVE_NTGUI */
1962 static int x_create_x_image_and_pixmap (struct frame
*, int, int, int,
1963 XImagePtr
*, Pixmap
*);
1964 static void x_destroy_x_image (XImagePtr
);
1965 static void x_put_x_image (struct frame
*, XImagePtr
, Pixmap
, int, int);
1968 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
1969 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
1970 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
1971 via xmalloc. Print error messages via image_error if an error
1972 occurs. Value is non-zero if successful.
1974 On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
1975 should indicate the bit depth of the image. */
1978 x_create_x_image_and_pixmap (struct frame
*f
, int width
, int height
, int depth
,
1979 XImagePtr
*ximg
, Pixmap
*pixmap
)
1981 #ifdef HAVE_X_WINDOWS
1982 Display
*display
= FRAME_X_DISPLAY (f
);
1983 Window window
= FRAME_X_WINDOW (f
);
1984 Screen
*screen
= FRAME_X_SCREEN (f
);
1986 xassert (interrupt_input_blocked
);
1989 depth
= DefaultDepthOfScreen (screen
);
1990 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
1991 depth
, ZPixmap
, 0, NULL
, width
, height
,
1992 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
1995 image_error ("Unable to allocate X image", Qnil
, Qnil
);
1999 /* Allocate image raster. */
2000 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
2002 /* Allocate a pixmap of the same size. */
2003 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
2004 if (*pixmap
== NO_PIXMAP
)
2006 x_destroy_x_image (*ximg
);
2008 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
2013 #endif /* HAVE_X_WINDOWS */
2017 BITMAPINFOHEADER
*header
;
2019 int scanline_width_bits
;
2021 int palette_colors
= 0;
2026 if (depth
!= 1 && depth
!= 4 && depth
!= 8
2027 && depth
!= 16 && depth
!= 24 && depth
!= 32)
2029 image_error ("Invalid image bit depth specified", Qnil
, Qnil
);
2033 scanline_width_bits
= width
* depth
;
2034 remainder
= scanline_width_bits
% 32;
2037 scanline_width_bits
+= 32 - remainder
;
2039 /* Bitmaps with a depth less than 16 need a palette. */
2040 /* BITMAPINFO structure already contains the first RGBQUAD. */
2042 palette_colors
= 1 << depth
- 1;
2044 *ximg
= xmalloc (sizeof (XImage
) + palette_colors
* sizeof (RGBQUAD
));
2047 image_error ("Unable to allocate memory for XImage", Qnil
, Qnil
);
2051 header
= &(*ximg
)->info
.bmiHeader
;
2052 memset (&(*ximg
)->info
, 0, sizeof (BITMAPINFO
));
2053 header
->biSize
= sizeof (*header
);
2054 header
->biWidth
= width
;
2055 header
->biHeight
= -height
; /* negative indicates a top-down bitmap. */
2056 header
->biPlanes
= 1;
2057 header
->biBitCount
= depth
;
2058 header
->biCompression
= BI_RGB
;
2059 header
->biClrUsed
= palette_colors
;
2061 /* TODO: fill in palette. */
2064 (*ximg
)->info
.bmiColors
[0].rgbBlue
= 0;
2065 (*ximg
)->info
.bmiColors
[0].rgbGreen
= 0;
2066 (*ximg
)->info
.bmiColors
[0].rgbRed
= 0;
2067 (*ximg
)->info
.bmiColors
[0].rgbReserved
= 0;
2068 (*ximg
)->info
.bmiColors
[1].rgbBlue
= 255;
2069 (*ximg
)->info
.bmiColors
[1].rgbGreen
= 255;
2070 (*ximg
)->info
.bmiColors
[1].rgbRed
= 255;
2071 (*ximg
)->info
.bmiColors
[1].rgbReserved
= 0;
2074 hdc
= get_frame_dc (f
);
2076 /* Create a DIBSection and raster array for the bitmap,
2077 and store its handle in *pixmap. */
2078 *pixmap
= CreateDIBSection (hdc
, &((*ximg
)->info
),
2079 (depth
< 16) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
,
2080 /* casting avoids a GCC warning */
2081 (void **)&((*ximg
)->data
), NULL
, 0);
2083 /* Realize display palette and garbage all frames. */
2084 release_frame_dc (f
, hdc
);
2086 if (*pixmap
== NULL
)
2088 DWORD err
= GetLastError ();
2089 Lisp_Object errcode
;
2090 /* All system errors are < 10000, so the following is safe. */
2091 XSETINT (errcode
, (int) err
);
2092 image_error ("Unable to create bitmap, error code %d", errcode
, Qnil
);
2093 x_destroy_x_image (*ximg
);
2099 #endif /* HAVE_NTGUI */
2102 *pixmap
= ns_image_for_XPM (width
, height
, depth
);
2106 image_error ("Unable to allocate NSImage for XPM pixmap", Qnil
, Qnil
);
2115 /* Destroy XImage XIMG. Free XIMG->data. */
2118 x_destroy_x_image (XImagePtr ximg
)
2120 xassert (interrupt_input_blocked
);
2123 #ifdef HAVE_X_WINDOWS
2126 XDestroyImage (ximg
);
2127 #endif /* HAVE_X_WINDOWS */
2129 /* Data will be freed by DestroyObject. */
2132 #endif /* HAVE_NTGUI */
2134 ns_release_object (ximg
);
2135 #endif /* HAVE_NS */
2140 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
2141 are width and height of both the image and pixmap. */
2144 x_put_x_image (struct frame
*f
, XImagePtr ximg
, Pixmap pixmap
, int width
, int height
)
2146 #ifdef HAVE_X_WINDOWS
2149 xassert (interrupt_input_blocked
);
2150 gc
= XCreateGC (FRAME_X_DISPLAY (f
), pixmap
, 0, NULL
);
2151 XPutImage (FRAME_X_DISPLAY (f
), pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
2152 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
2153 #endif /* HAVE_X_WINDOWS */
2156 #if 0 /* I don't think this is necessary looking at where it is used. */
2157 HDC hdc
= get_frame_dc (f
);
2158 SetDIBits (hdc
, pixmap
, 0, height
, ximg
->data
, &(ximg
->info
), DIB_RGB_COLORS
);
2159 release_frame_dc (f
, hdc
);
2161 #endif /* HAVE_NTGUI */
2164 xassert (ximg
== pixmap
);
2165 ns_retain_object (ximg
);
2170 /***********************************************************************
2172 ***********************************************************************/
2174 static unsigned char *slurp_file (char *, int *);
2177 /* Find image file FILE. Look in data-directory/images, then
2178 x-bitmap-file-path. Value is the encoded full name of the file
2179 found, or nil if not found. */
2182 x_find_image_file (Lisp_Object file
)
2184 Lisp_Object file_found
, search_path
;
2185 struct gcpro gcpro1
, gcpro2
;
2189 /* TODO I think this should use something like image-load-path
2190 instead. Unfortunately, that can contain non-string elements. */
2191 search_path
= Fcons (Fexpand_file_name (build_string ("images"),
2193 Vx_bitmap_file_path
);
2194 GCPRO2 (file_found
, search_path
);
2196 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
2197 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
2203 file_found
= ENCODE_FILE (file_found
);
2212 /* Read FILE into memory. Value is a pointer to a buffer allocated
2213 with xmalloc holding FILE's contents. Value is null if an error
2214 occurred. *SIZE is set to the size of the file. */
2216 static unsigned char *
2217 slurp_file (char *file
, int *size
)
2220 unsigned char *buf
= NULL
;
2223 if (stat (file
, &st
) == 0
2224 && (fp
= fopen (file
, "rb")) != NULL
2225 && (buf
= (unsigned char *) xmalloc (st
.st_size
),
2226 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
2247 /***********************************************************************
2249 ***********************************************************************/
2251 static int xbm_scan (unsigned char **, unsigned char *, char *, int *);
2252 static int xbm_load (struct frame
*f
, struct image
*img
);
2253 static int xbm_load_image (struct frame
*f
, struct image
*img
,
2254 unsigned char *, unsigned char *);
2255 static int xbm_image_p (Lisp_Object object
);
2256 static int xbm_read_bitmap_data (struct frame
*f
,
2257 unsigned char *, unsigned char *,
2258 int *, int *, unsigned char **, int);
2259 static int xbm_file_p (Lisp_Object
);
2262 /* Indices of image specification fields in xbm_format, below. */
2264 enum xbm_keyword_index
2282 /* Vector of image_keyword structures describing the format
2283 of valid XBM image specifications. */
2285 static const struct image_keyword xbm_format
[XBM_LAST
] =
2287 {":type", IMAGE_SYMBOL_VALUE
, 1},
2288 {":file", IMAGE_STRING_VALUE
, 0},
2289 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2290 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2291 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2292 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
2293 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
2294 {":ascent", IMAGE_ASCENT_VALUE
, 0},
2295 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
2296 {":relief", IMAGE_INTEGER_VALUE
, 0},
2297 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2298 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2299 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
2302 /* Structure describing the image type XBM. */
2304 static struct image_type xbm_type
=
2313 /* Tokens returned from xbm_scan. */
2322 /* Return non-zero if OBJECT is a valid XBM-type image specification.
2323 A valid specification is a list starting with the symbol `image'
2324 The rest of the list is a property list which must contain an
2327 If the specification specifies a file to load, it must contain
2328 an entry `:file FILENAME' where FILENAME is a string.
2330 If the specification is for a bitmap loaded from memory it must
2331 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
2332 WIDTH and HEIGHT are integers > 0. DATA may be:
2334 1. a string large enough to hold the bitmap data, i.e. it must
2335 have a size >= (WIDTH + 7) / 8 * HEIGHT
2337 2. a bool-vector of size >= WIDTH * HEIGHT
2339 3. a vector of strings or bool-vectors, one for each line of the
2342 4. a string containing an in-memory XBM file. WIDTH and HEIGHT
2343 may not be specified in this case because they are defined in the
2346 Both the file and data forms may contain the additional entries
2347 `:background COLOR' and `:foreground COLOR'. If not present,
2348 foreground and background of the frame on which the image is
2349 displayed is used. */
2352 xbm_image_p (Lisp_Object object
)
2354 struct image_keyword kw
[XBM_LAST
];
2356 memcpy (kw
, xbm_format
, sizeof kw
);
2357 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
2360 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
2362 if (kw
[XBM_FILE
].count
)
2364 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
2367 else if (kw
[XBM_DATA
].count
&& xbm_file_p (kw
[XBM_DATA
].value
))
2369 /* In-memory XBM file. */
2370 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_FILE
].count
)
2378 /* Entries for `:width', `:height' and `:data' must be present. */
2379 if (!kw
[XBM_WIDTH
].count
2380 || !kw
[XBM_HEIGHT
].count
2381 || !kw
[XBM_DATA
].count
)
2384 data
= kw
[XBM_DATA
].value
;
2385 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
2386 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
2388 /* Check type of data, and width and height against contents of
2394 /* Number of elements of the vector must be >= height. */
2395 if (XVECTOR (data
)->size
< height
)
2398 /* Each string or bool-vector in data must be large enough
2399 for one line of the image. */
2400 for (i
= 0; i
< height
; ++i
)
2402 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
2407 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
2410 else if (BOOL_VECTOR_P (elt
))
2412 if (XBOOL_VECTOR (elt
)->size
< width
)
2419 else if (STRINGP (data
))
2422 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
2425 else if (BOOL_VECTOR_P (data
))
2427 if (XBOOL_VECTOR (data
)->size
< width
* height
)
2438 /* Scan a bitmap file. FP is the stream to read from. Value is
2439 either an enumerator from enum xbm_token, or a character for a
2440 single-character token, or 0 at end of file. If scanning an
2441 identifier, store the lexeme of the identifier in SVAL. If
2442 scanning a number, store its value in *IVAL. */
2445 xbm_scan (unsigned char **s
, unsigned char *end
, char *sval
, int *ival
)
2451 /* Skip white space. */
2452 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
2457 else if (isdigit (c
))
2459 int value
= 0, digit
;
2461 if (c
== '0' && *s
< end
)
2464 if (c
== 'x' || c
== 'X')
2471 else if (c
>= 'a' && c
<= 'f')
2472 digit
= c
- 'a' + 10;
2473 else if (c
>= 'A' && c
<= 'F')
2474 digit
= c
- 'A' + 10;
2477 value
= 16 * value
+ digit
;
2480 else if (isdigit (c
))
2484 && (c
= *(*s
)++, isdigit (c
)))
2485 value
= 8 * value
+ c
- '0';
2492 && (c
= *(*s
)++, isdigit (c
)))
2493 value
= 10 * value
+ c
- '0';
2501 else if (isalpha (c
) || c
== '_')
2505 && (c
= *(*s
)++, (isalnum (c
) || c
== '_')))
2512 else if (c
== '/' && **s
== '*')
2514 /* C-style comment. */
2516 while (**s
&& (**s
!= '*' || *(*s
+ 1) != '/'))
2530 /* Create a Windows bitmap from X bitmap data. */
2532 w32_create_pixmap_from_bitmap_data (int width
, int height
, char *data
)
2534 static unsigned char swap_nibble
[16]
2535 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
2536 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
2537 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
2538 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
2540 unsigned char *bits
, *p
;
2543 w1
= (width
+ 7) / 8; /* nb of 8bits elt in X bitmap */
2544 w2
= ((width
+ 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
2545 bits
= (unsigned char *) alloca (height
* w2
);
2546 memset (bits
, 0, height
* w2
);
2547 for (i
= 0; i
< height
; i
++)
2550 for (j
= 0; j
< w1
; j
++)
2552 /* Bitswap XBM bytes to match how Windows does things. */
2553 unsigned char c
= *data
++;
2554 *p
++ = (unsigned char)((swap_nibble
[c
& 0xf] << 4)
2555 | (swap_nibble
[(c
>>4) & 0xf]));
2558 bmp
= CreateBitmap (width
, height
, 1, 1, (char *) bits
);
2564 convert_mono_to_color_image (f
, img
, foreground
, background
)
2567 COLORREF foreground
, background
;
2569 HDC hdc
, old_img_dc
, new_img_dc
;
2570 HGDIOBJ old_prev
, new_prev
;
2573 hdc
= get_frame_dc (f
);
2574 old_img_dc
= CreateCompatibleDC (hdc
);
2575 new_img_dc
= CreateCompatibleDC (hdc
);
2576 new_pixmap
= CreateCompatibleBitmap (hdc
, img
->width
, img
->height
);
2577 release_frame_dc (f
, hdc
);
2578 old_prev
= SelectObject (old_img_dc
, img
->pixmap
);
2579 new_prev
= SelectObject (new_img_dc
, new_pixmap
);
2580 /* Windows convention for mono bitmaps is black = background,
2581 white = foreground. */
2582 SetTextColor (new_img_dc
, background
);
2583 SetBkColor (new_img_dc
, foreground
);
2585 BitBlt (new_img_dc
, 0, 0, img
->width
, img
->height
, old_img_dc
,
2588 SelectObject (old_img_dc
, old_prev
);
2589 SelectObject (new_img_dc
, new_prev
);
2590 DeleteDC (old_img_dc
);
2591 DeleteDC (new_img_dc
);
2592 DeleteObject (img
->pixmap
);
2593 if (new_pixmap
== 0)
2594 fprintf (stderr
, "Failed to convert image to color.\n");
2596 img
->pixmap
= new_pixmap
;
2599 #define XBM_BIT_SHUFFLE(b) (~(b))
2603 #define XBM_BIT_SHUFFLE(b) (b)
2605 #endif /* HAVE_NTGUI */
2609 Create_Pixmap_From_Bitmap_Data (struct frame
*f
, struct image
*img
, char *data
,
2610 RGB_PIXEL_COLOR fg
, RGB_PIXEL_COLOR bg
,
2611 int non_default_colors
)
2615 = w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
, data
);
2617 /* If colors were specified, transfer the bitmap to a color one. */
2618 if (non_default_colors
)
2619 convert_mono_to_color_image (f
, img
, fg
, bg
);
2621 #elif defined (HAVE_NS)
2622 img
->pixmap
= ns_image_from_XBM (data
, img
->width
, img
->height
);
2626 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
2629 img
->width
, img
->height
,
2631 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
2632 #endif /* !HAVE_NTGUI && !HAVE_NS */
2637 /* Replacement for XReadBitmapFileData which isn't available under old
2638 X versions. CONTENTS is a pointer to a buffer to parse; END is the
2639 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
2640 the image. Return in *DATA the bitmap data allocated with xmalloc.
2641 Value is non-zero if successful. DATA null means just test if
2642 CONTENTS looks like an in-memory XBM file. If INHIBIT_IMAGE_ERROR
2643 is non-zero, inhibit the call to image_error when the image size is
2644 invalid (the bitmap remains unread). */
2647 xbm_read_bitmap_data (struct frame
*f
, unsigned char *contents
, unsigned char *end
,
2648 int *width
, int *height
, unsigned char **data
,
2649 int inhibit_image_error
)
2651 unsigned char *s
= contents
;
2652 char buffer
[BUFSIZ
];
2655 int bytes_per_line
, i
, nbytes
;
2661 LA1 = xbm_scan (&s, end, buffer, &value)
2663 #define expect(TOKEN) \
2664 if (LA1 != (TOKEN)) \
2669 #define expect_ident(IDENT) \
2670 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
2675 *width
= *height
= -1;
2678 LA1
= xbm_scan (&s
, end
, buffer
, &value
);
2680 /* Parse defines for width, height and hot-spots. */
2684 expect_ident ("define");
2685 expect (XBM_TK_IDENT
);
2687 if (LA1
== XBM_TK_NUMBER
)
2689 char *p
= strrchr (buffer
, '_');
2690 p
= p
? p
+ 1 : buffer
;
2691 if (strcmp (p
, "width") == 0)
2693 else if (strcmp (p
, "height") == 0)
2696 expect (XBM_TK_NUMBER
);
2699 if (!check_image_size (f
, *width
, *height
))
2701 if (!inhibit_image_error
)
2702 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
2705 else if (data
== NULL
)
2708 /* Parse bits. Must start with `static'. */
2709 expect_ident ("static");
2710 if (LA1
== XBM_TK_IDENT
)
2712 if (strcmp (buffer
, "unsigned") == 0)
2715 expect_ident ("char");
2717 else if (strcmp (buffer
, "short") == 0)
2721 if (*width
% 16 && *width
% 16 < 9)
2724 else if (strcmp (buffer
, "char") == 0)
2732 expect (XBM_TK_IDENT
);
2738 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
2739 nbytes
= bytes_per_line
* *height
;
2740 p
= *data
= (unsigned char *) xmalloc (nbytes
);
2744 for (i
= 0; i
< nbytes
; i
+= 2)
2747 expect (XBM_TK_NUMBER
);
2749 *p
++ = XBM_BIT_SHUFFLE (val
);
2750 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
2751 *p
++ = XBM_BIT_SHUFFLE (value
>> 8);
2753 if (LA1
== ',' || LA1
== '}')
2761 for (i
= 0; i
< nbytes
; ++i
)
2764 expect (XBM_TK_NUMBER
);
2766 *p
++ = XBM_BIT_SHUFFLE (val
);
2768 if (LA1
== ',' || LA1
== '}')
2793 /* Load XBM image IMG which will be displayed on frame F from buffer
2794 CONTENTS. END is the end of the buffer. Value is non-zero if
2798 xbm_load_image (struct frame
*f
, struct image
*img
, unsigned char *contents
,
2802 unsigned char *data
;
2805 rc
= xbm_read_bitmap_data (f
, contents
, end
, &img
->width
, &img
->height
,
2809 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2810 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2811 int non_default_colors
= 0;
2814 xassert (img
->width
> 0 && img
->height
> 0);
2816 /* Get foreground and background colors, maybe allocate colors. */
2817 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
2820 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
2821 non_default_colors
= 1;
2823 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
2826 background
= x_alloc_image_color (f
, img
, value
, background
);
2827 img
->background
= background
;
2828 img
->background_valid
= 1;
2829 non_default_colors
= 1;
2832 Create_Pixmap_From_Bitmap_Data (f
, img
, data
,
2833 foreground
, background
,
2834 non_default_colors
);
2837 if (img
->pixmap
== NO_PIXMAP
)
2839 x_clear_image (f
, img
);
2840 image_error ("Unable to create X pixmap for `%s'", img
->spec
, Qnil
);
2846 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
2852 /* Value is non-zero if DATA looks like an in-memory XBM file. */
2855 xbm_file_p (Lisp_Object data
)
2858 return (STRINGP (data
)
2859 && xbm_read_bitmap_data (NULL
, SDATA (data
),
2860 (SDATA (data
) + SBYTES (data
)),
2865 /* Fill image IMG which is used on frame F with pixmap data. Value is
2866 non-zero if successful. */
2869 xbm_load (struct frame
*f
, struct image
*img
)
2872 Lisp_Object file_name
;
2874 xassert (xbm_image_p (img
->spec
));
2876 /* If IMG->spec specifies a file name, create a non-file spec from it. */
2877 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
2878 if (STRINGP (file_name
))
2881 unsigned char *contents
;
2883 struct gcpro gcpro1
;
2885 file
= x_find_image_file (file_name
);
2887 if (!STRINGP (file
))
2889 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
2894 contents
= slurp_file (SDATA (file
), &size
);
2895 if (contents
== NULL
)
2897 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
2902 success_p
= xbm_load_image (f
, img
, contents
, contents
+ size
);
2907 struct image_keyword fmt
[XBM_LAST
];
2909 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2910 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2911 int non_default_colors
= 0;
2914 int in_memory_file_p
= 0;
2916 /* See if data looks like an in-memory XBM file. */
2917 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
2918 in_memory_file_p
= xbm_file_p (data
);
2920 /* Parse the image specification. */
2921 memcpy (fmt
, xbm_format
, sizeof fmt
);
2922 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
2925 /* Get specified width, and height. */
2926 if (!in_memory_file_p
)
2928 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
2929 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
2930 xassert (img
->width
> 0 && img
->height
> 0);
2933 /* Get foreground and background colors, maybe allocate colors. */
2934 if (fmt
[XBM_FOREGROUND
].count
2935 && STRINGP (fmt
[XBM_FOREGROUND
].value
))
2937 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
2939 non_default_colors
= 1;
2942 if (fmt
[XBM_BACKGROUND
].count
2943 && STRINGP (fmt
[XBM_BACKGROUND
].value
))
2945 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
2947 non_default_colors
= 1;
2950 if (in_memory_file_p
)
2951 success_p
= xbm_load_image (f
, img
, SDATA (data
),
2960 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
2962 p
= bits
= (char *) alloca (nbytes
* img
->height
);
2963 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
2965 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
2967 memcpy (p
, SDATA (line
), nbytes
);
2969 memcpy (p
, XBOOL_VECTOR (line
)->data
, nbytes
);
2972 else if (STRINGP (data
))
2973 bits
= SDATA (data
);
2975 bits
= XBOOL_VECTOR (data
)->data
;
2981 /* Windows mono bitmaps are reversed compared with X. */
2982 invertedBits
= bits
;
2983 nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
2985 bits
= (char *) alloca (nbytes
);
2986 for (i
= 0; i
< nbytes
; i
++)
2987 bits
[i
] = XBM_BIT_SHUFFLE (invertedBits
[i
]);
2990 /* Create the pixmap. */
2992 Create_Pixmap_From_Bitmap_Data (f
, img
, bits
,
2993 foreground
, background
,
2994 non_default_colors
);
2999 image_error ("Unable to create pixmap for XBM image `%s'",
3001 x_clear_image (f
, img
);
3011 /***********************************************************************
3013 ***********************************************************************/
3015 #if defined (HAVE_XPM) || defined (HAVE_NS)
3017 static int xpm_image_p (Lisp_Object object
);
3018 static int xpm_load (struct frame
*f
, struct image
*img
);
3019 static int xpm_valid_color_symbols_p (Lisp_Object
);
3021 #endif /* HAVE_XPM || HAVE_NS */
3025 /* Indicate to xpm.h that we don't have Xlib. */
3027 /* simx.h in xpm defines XColor and XImage differently than Emacs. */
3028 /* It also defines Display the same way as Emacs, but gcc 3.3 still barfs. */
3029 #define XColor xpm_XColor
3030 #define XImage xpm_XImage
3031 #define Display xpm_Display
3032 #define PIXEL_ALREADY_TYPEDEFED
3033 #include "X11/xpm.h"
3038 #undef PIXEL_ALREADY_TYPEDEFED
3040 #include "X11/xpm.h"
3041 #endif /* HAVE_NTGUI */
3042 #endif /* HAVE_XPM */
3044 #if defined (HAVE_XPM) || defined (HAVE_NS)
3045 /* The symbol `xpm' identifying XPM-format images. */
3049 /* Indices of image specification fields in xpm_format, below. */
3051 enum xpm_keyword_index
3067 /* Vector of image_keyword structures describing the format
3068 of valid XPM image specifications. */
3070 static const struct image_keyword xpm_format
[XPM_LAST
] =
3072 {":type", IMAGE_SYMBOL_VALUE
, 1},
3073 {":file", IMAGE_STRING_VALUE
, 0},
3074 {":data", IMAGE_STRING_VALUE
, 0},
3075 {":ascent", IMAGE_ASCENT_VALUE
, 0},
3076 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
3077 {":relief", IMAGE_INTEGER_VALUE
, 0},
3078 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3079 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3080 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3081 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3082 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
3085 /* Structure describing the image type XPM. */
3087 static struct image_type xpm_type
=
3096 #ifdef HAVE_X_WINDOWS
3098 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
3099 functions for allocating image colors. Our own functions handle
3100 color allocation failures more gracefully than the ones on the XPM
3103 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
3104 #define ALLOC_XPM_COLORS
3106 #endif /* HAVE_X_WINDOWS */
3108 #ifdef ALLOC_XPM_COLORS
3110 static void xpm_init_color_cache (struct frame
*, XpmAttributes
*);
3111 static void xpm_free_color_cache (void);
3112 static int xpm_lookup_color (struct frame
*, char *, XColor
*);
3113 static int xpm_color_bucket (char *);
3114 static struct xpm_cached_color
*xpm_cache_color (struct frame
*, char *,
3117 /* An entry in a hash table used to cache color definitions of named
3118 colors. This cache is necessary to speed up XPM image loading in
3119 case we do color allocations ourselves. Without it, we would need
3120 a call to XParseColor per pixel in the image. */
3122 struct xpm_cached_color
3124 /* Next in collision chain. */
3125 struct xpm_cached_color
*next
;
3127 /* Color definition (RGB and pixel color). */
3134 /* The hash table used for the color cache, and its bucket vector
3137 #define XPM_COLOR_CACHE_BUCKETS 1001
3138 struct xpm_cached_color
**xpm_color_cache
;
3140 /* Initialize the color cache. */
3143 xpm_init_color_cache (struct frame
*f
, XpmAttributes
*attrs
)
3145 size_t nbytes
= XPM_COLOR_CACHE_BUCKETS
* sizeof *xpm_color_cache
;
3146 xpm_color_cache
= (struct xpm_cached_color
**) xmalloc (nbytes
);
3147 memset (xpm_color_cache
, 0, nbytes
);
3148 init_color_table ();
3150 if (attrs
->valuemask
& XpmColorSymbols
)
3155 for (i
= 0; i
< attrs
->numsymbols
; ++i
)
3156 if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
3157 attrs
->colorsymbols
[i
].value
, &color
))
3159 color
.pixel
= lookup_rgb_color (f
, color
.red
, color
.green
,
3161 xpm_cache_color (f
, attrs
->colorsymbols
[i
].name
, &color
, -1);
3166 /* Free the color cache. */
3169 xpm_free_color_cache (void)
3171 struct xpm_cached_color
*p
, *next
;
3174 for (i
= 0; i
< XPM_COLOR_CACHE_BUCKETS
; ++i
)
3175 for (p
= xpm_color_cache
[i
]; p
; p
= next
)
3181 xfree (xpm_color_cache
);
3182 xpm_color_cache
= NULL
;
3183 free_color_table ();
3186 /* Return the bucket index for color named COLOR_NAME in the color
3190 xpm_color_bucket (char *color_name
)
3195 for (s
= color_name
; *s
; ++s
)
3197 return h
%= XPM_COLOR_CACHE_BUCKETS
;
3201 /* On frame F, cache values COLOR for color with name COLOR_NAME.
3202 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
3205 static struct xpm_cached_color
*
3206 xpm_cache_color (struct frame
*f
, char *color_name
, XColor
*color
, int bucket
)
3209 struct xpm_cached_color
*p
;
3212 bucket
= xpm_color_bucket (color_name
);
3214 nbytes
= sizeof *p
+ strlen (color_name
);
3215 p
= (struct xpm_cached_color
*) xmalloc (nbytes
);
3216 strcpy (p
->name
, color_name
);
3218 p
->next
= xpm_color_cache
[bucket
];
3219 xpm_color_cache
[bucket
] = p
;
3223 /* Look up color COLOR_NAME for frame F in the color cache. If found,
3224 return the cached definition in *COLOR. Otherwise, make a new
3225 entry in the cache and allocate the color. Value is zero if color
3226 allocation failed. */
3229 xpm_lookup_color (struct frame
*f
, char *color_name
, XColor
*color
)
3231 struct xpm_cached_color
*p
;
3232 int h
= xpm_color_bucket (color_name
);
3234 for (p
= xpm_color_cache
[h
]; p
; p
= p
->next
)
3235 if (strcmp (p
->name
, color_name
) == 0)
3240 else if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
3243 color
->pixel
= lookup_rgb_color (f
, color
->red
, color
->green
,
3245 p
= xpm_cache_color (f
, color_name
, color
, h
);
3247 /* You get `opaque' at least from ImageMagick converting pbm to xpm
3248 with transparency, and it's useful. */
3249 else if (strcmp ("opaque", color_name
) == 0)
3251 memset (color
, 0, sizeof (XColor
)); /* Is this necessary/correct? */
3252 color
->pixel
= FRAME_FOREGROUND_PIXEL (f
);
3253 p
= xpm_cache_color (f
, color_name
, color
, h
);
3260 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
3261 CLOSURE is a pointer to the frame on which we allocate the
3262 color. Return in *COLOR the allocated color. Value is non-zero
3266 xpm_alloc_color (Display
*dpy
, Colormap cmap
, char *color_name
, XColor
*color
,
3269 return xpm_lookup_color ((struct frame
*) closure
, color_name
, color
);
3273 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
3274 is a pointer to the frame on which we allocate the color. Value is
3275 non-zero if successful. */
3278 xpm_free_colors (Display
*dpy
, Colormap cmap
, Pixel
*pixels
, int npixels
, void *closure
)
3283 #endif /* ALLOC_XPM_COLORS */
3288 /* XPM library details. */
3290 DEF_IMGLIB_FN (XpmFreeAttributes
);
3291 DEF_IMGLIB_FN (XpmCreateImageFromBuffer
);
3292 DEF_IMGLIB_FN (XpmReadFileToImage
);
3293 DEF_IMGLIB_FN (XImageFree
);
3296 init_xpm_functions (Lisp_Object libraries
)
3300 if (!(library
= w32_delayed_load (libraries
, Qxpm
)))
3303 LOAD_IMGLIB_FN (library
, XpmFreeAttributes
);
3304 LOAD_IMGLIB_FN (library
, XpmCreateImageFromBuffer
);
3305 LOAD_IMGLIB_FN (library
, XpmReadFileToImage
);
3306 LOAD_IMGLIB_FN (library
, XImageFree
);
3310 #endif /* HAVE_NTGUI */
3313 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
3314 for XPM images. Such a list must consist of conses whose car and
3318 xpm_valid_color_symbols_p (Lisp_Object color_symbols
)
3320 while (CONSP (color_symbols
))
3322 Lisp_Object sym
= XCAR (color_symbols
);
3324 || !STRINGP (XCAR (sym
))
3325 || !STRINGP (XCDR (sym
)))
3327 color_symbols
= XCDR (color_symbols
);
3330 return NILP (color_symbols
);
3334 /* Value is non-zero if OBJECT is a valid XPM image specification. */
3337 xpm_image_p (Lisp_Object object
)
3339 struct image_keyword fmt
[XPM_LAST
];
3340 memcpy (fmt
, xpm_format
, sizeof fmt
);
3341 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
3342 /* Either `:file' or `:data' must be present. */
3343 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
3344 /* Either no `:color-symbols' or it's a list of conses
3345 whose car and cdr are strings. */
3346 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
3347 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
)));
3350 #endif /* HAVE_XPM || HAVE_NS */
3352 #if defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
3354 x_create_bitmap_from_xpm_data (struct frame
*f
, char **bits
)
3356 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3358 XpmAttributes attrs
;
3359 Pixmap bitmap
, mask
;
3361 memset (&attrs
, 0, sizeof attrs
);
3363 attrs
.visual
= FRAME_X_VISUAL (f
);
3364 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3365 attrs
.valuemask
|= XpmVisual
;
3366 attrs
.valuemask
|= XpmColormap
;
3368 rc
= XpmCreatePixmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3369 bits
, &bitmap
, &mask
, &attrs
);
3370 if (rc
!= XpmSuccess
)
3372 XpmFreeAttributes (&attrs
);
3376 id
= x_allocate_bitmap_record (f
);
3377 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
3378 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
3379 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
3380 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
3381 dpyinfo
->bitmaps
[id
- 1].height
= attrs
.height
;
3382 dpyinfo
->bitmaps
[id
- 1].width
= attrs
.width
;
3383 dpyinfo
->bitmaps
[id
- 1].depth
= attrs
.depth
;
3384 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
3386 XpmFreeAttributes (&attrs
);
3389 #endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */
3391 /* Load image IMG which will be displayed on frame F. Value is
3392 non-zero if successful. */
3397 xpm_load (struct frame
*f
, struct image
*img
)
3400 XpmAttributes attrs
;
3401 Lisp_Object specified_file
, color_symbols
;
3404 xpm_XImage
* xpm_image
= NULL
, * xpm_mask
= NULL
;
3405 #endif /* HAVE_NTGUI */
3407 /* Configure the XPM lib. Use the visual of frame F. Allocate
3408 close colors. Return colors allocated. */
3409 memset (&attrs
, 0, sizeof attrs
);
3412 attrs
.visual
= FRAME_X_VISUAL (f
);
3413 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3414 attrs
.valuemask
|= XpmVisual
;
3415 attrs
.valuemask
|= XpmColormap
;
3416 #endif /* HAVE_NTGUI */
3418 #ifdef ALLOC_XPM_COLORS
3419 /* Allocate colors with our own functions which handle
3420 failing color allocation more gracefully. */
3421 attrs
.color_closure
= f
;
3422 attrs
.alloc_color
= xpm_alloc_color
;
3423 attrs
.free_colors
= xpm_free_colors
;
3424 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
3425 #else /* not ALLOC_XPM_COLORS */
3426 /* Let the XPM lib allocate colors. */
3427 attrs
.valuemask
|= XpmReturnAllocPixels
;
3428 #ifdef XpmAllocCloseColors
3429 attrs
.alloc_close_colors
= 1;
3430 attrs
.valuemask
|= XpmAllocCloseColors
;
3431 #else /* not XpmAllocCloseColors */
3432 attrs
.closeness
= 600;
3433 attrs
.valuemask
|= XpmCloseness
;
3434 #endif /* not XpmAllocCloseColors */
3435 #endif /* ALLOC_XPM_COLORS */
3437 /* If image specification contains symbolic color definitions, add
3438 these to `attrs'. */
3439 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
3440 if (CONSP (color_symbols
))
3443 XpmColorSymbol
*xpm_syms
;
3446 attrs
.valuemask
|= XpmColorSymbols
;
3448 /* Count number of symbols. */
3449 attrs
.numsymbols
= 0;
3450 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
3453 /* Allocate an XpmColorSymbol array. */
3454 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
3455 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
3456 memset (xpm_syms
, 0, size
);
3457 attrs
.colorsymbols
= xpm_syms
;
3459 /* Fill the color symbol array. */
3460 for (tail
= color_symbols
, i
= 0;
3462 ++i
, tail
= XCDR (tail
))
3464 Lisp_Object name
= XCAR (XCAR (tail
));
3465 Lisp_Object color
= XCDR (XCAR (tail
));
3466 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
3467 strcpy (xpm_syms
[i
].name
, SDATA (name
));
3468 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
3469 strcpy (xpm_syms
[i
].value
, SDATA (color
));
3473 /* Create a pixmap for the image, either from a file, or from a
3474 string buffer containing data in the same format as an XPM file. */
3475 #ifdef ALLOC_XPM_COLORS
3476 xpm_init_color_cache (f
, &attrs
);
3479 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
3483 HDC frame_dc
= get_frame_dc (f
);
3484 hdc
= CreateCompatibleDC (frame_dc
);
3485 release_frame_dc (f
, frame_dc
);
3487 #endif /* HAVE_NTGUI */
3489 if (STRINGP (specified_file
))
3491 Lisp_Object file
= x_find_image_file (specified_file
);
3492 if (!STRINGP (file
))
3494 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
3499 /* XpmReadFileToPixmap is not available in the Windows port of
3500 libxpm. But XpmReadFileToImage almost does what we want. */
3501 rc
= fn_XpmReadFileToImage (&hdc
, SDATA (file
),
3502 &xpm_image
, &xpm_mask
,
3505 rc
= XpmReadFileToPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3506 SDATA (file
), &img
->pixmap
, &img
->mask
,
3508 #endif /* HAVE_NTGUI */
3512 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
3514 /* XpmCreatePixmapFromBuffer is not available in the Windows port
3515 of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
3516 rc
= fn_XpmCreateImageFromBuffer (&hdc
, SDATA (buffer
),
3517 &xpm_image
, &xpm_mask
,
3520 rc
= XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3522 &img
->pixmap
, &img
->mask
,
3524 #endif /* HAVE_NTGUI */
3527 if (rc
== XpmSuccess
)
3529 #if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS)
3530 img
->colors
= colors_in_color_table (&img
->ncolors
);
3531 #else /* not ALLOC_XPM_COLORS */
3535 /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
3536 plus some duplicate attributes. */
3537 if (xpm_image
&& xpm_image
->bitmap
)
3539 img
->pixmap
= xpm_image
->bitmap
;
3540 /* XImageFree in libXpm frees XImage struct without destroying
3541 the bitmap, which is what we want. */
3542 fn_XImageFree (xpm_image
);
3544 if (xpm_mask
&& xpm_mask
->bitmap
)
3546 /* The mask appears to be inverted compared with what we expect.
3547 TODO: invert our expectations. See other places where we
3548 have to invert bits because our idea of masks is backwards. */
3550 old_obj
= SelectObject (hdc
, xpm_mask
->bitmap
);
3552 PatBlt (hdc
, 0, 0, xpm_mask
->width
, xpm_mask
->height
, DSTINVERT
);
3553 SelectObject (hdc
, old_obj
);
3555 img
->mask
= xpm_mask
->bitmap
;
3556 fn_XImageFree (xpm_mask
);
3561 #endif /* HAVE_NTGUI */
3563 /* Remember allocated colors. */
3564 img
->ncolors
= attrs
.nalloc_pixels
;
3565 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
3566 * sizeof *img
->colors
);
3567 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
3569 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
3570 #ifdef DEBUG_X_COLORS
3571 register_color (img
->colors
[i
]);
3574 #endif /* not ALLOC_XPM_COLORS */
3576 img
->width
= attrs
.width
;
3577 img
->height
= attrs
.height
;
3578 xassert (img
->width
> 0 && img
->height
> 0);
3580 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
3582 fn_XpmFreeAttributes (&attrs
);
3584 XpmFreeAttributes (&attrs
);
3585 #endif /* HAVE_NTGUI */
3591 #endif /* HAVE_NTGUI */
3596 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
3599 case XpmFileInvalid
:
3600 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
3604 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
3607 case XpmColorFailed
:
3608 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
3612 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
3617 #ifdef ALLOC_XPM_COLORS
3618 xpm_free_color_cache ();
3620 return rc
== XpmSuccess
;
3623 #endif /* HAVE_XPM */
3625 #if defined (HAVE_NS) && !defined (HAVE_XPM)
3627 /* XPM support functions for NS where libxpm is not available.
3628 Only XPM version 3 (without any extensions) is supported. */
3630 static int xpm_scan (const unsigned char **, const unsigned char *,
3631 const unsigned char **, int *);
3632 static Lisp_Object xpm_make_color_table_v
3633 (void (**) (Lisp_Object
, const unsigned char *, int, Lisp_Object
),
3634 Lisp_Object (**) (Lisp_Object
, const unsigned char *, int));
3635 static void xpm_put_color_table_v (Lisp_Object
, const unsigned char *,
3637 static Lisp_Object
xpm_get_color_table_v (Lisp_Object
,
3638 const unsigned char *, int);
3639 static Lisp_Object xpm_make_color_table_h
3640 (void (**) (Lisp_Object
, const unsigned char *, int, Lisp_Object
),
3641 Lisp_Object (**) (Lisp_Object
, const unsigned char *, int));
3642 static void xpm_put_color_table_h (Lisp_Object
, const unsigned char *,
3644 static Lisp_Object
xpm_get_color_table_h (Lisp_Object
,
3645 const unsigned char *, int);
3646 static int xpm_str_to_color_key (const char *);
3647 static int xpm_load_image (struct frame
*, struct image
*,
3648 const unsigned char *, const unsigned char *);
3650 /* Tokens returned from xpm_scan. */
3659 /* Scan an XPM data and return a character (< 256) or a token defined
3660 by enum xpm_token above. *S and END are the start (inclusive) and
3661 the end (exclusive) addresses of the data, respectively. Advance
3662 *S while scanning. If token is either XPM_TK_IDENT or
3663 XPM_TK_STRING, *BEG and *LEN are set to the start address and the
3664 length of the corresponding token, respectively. */
3667 xpm_scan (s
, end
, beg
, len
)
3668 const unsigned char **s
, *end
, **beg
;
3675 /* Skip white-space. */
3676 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
3679 /* gnus-pointer.xpm uses '-' in its identifier.
3680 sb-dir-plus.xpm uses '+' in its identifier. */
3681 if (isalpha (c
) || c
== '_' || c
== '-' || c
== '+')
3685 && (c
= **s
, isalnum (c
) || c
== '_' || c
== '-' || c
== '+'))
3688 return XPM_TK_IDENT
;
3693 while (*s
< end
&& **s
!= '"')
3698 return XPM_TK_STRING
;
3702 if (*s
< end
&& **s
== '*')
3704 /* C-style comment. */
3708 while (*s
< end
&& *(*s
)++ != '*')
3711 while (*s
< end
&& **s
!= '/');
3725 /* Functions for color table lookup in XPM data. A key is a string
3726 specifying the color of each pixel in XPM data. A value is either
3727 an integer that specifies a pixel color, Qt that specifies
3728 transparency, or Qnil for the unspecified color. If the length of
3729 the key string is one, a vector is used as a table. Otherwise, a
3730 hash table is used. */
3733 xpm_make_color_table_v (put_func
, get_func
)
3734 void (**put_func
) (Lisp_Object
, const unsigned char *, int, Lisp_Object
);
3735 Lisp_Object (**get_func
) (Lisp_Object
, const unsigned char *, int);
3737 *put_func
= xpm_put_color_table_v
;
3738 *get_func
= xpm_get_color_table_v
;
3739 return Fmake_vector (make_number (256), Qnil
);
3743 xpm_put_color_table_v (color_table
, chars_start
, chars_len
, color
)
3744 Lisp_Object color_table
;
3745 const unsigned char *chars_start
;
3749 XVECTOR (color_table
)->contents
[*chars_start
] = color
;
3753 xpm_get_color_table_v (color_table
, chars_start
, chars_len
)
3754 Lisp_Object color_table
;
3755 const unsigned char *chars_start
;
3758 return XVECTOR (color_table
)->contents
[*chars_start
];
3762 xpm_make_color_table_h (put_func
, get_func
)
3763 void (**put_func
) (Lisp_Object
, const unsigned char *, int, Lisp_Object
);
3764 Lisp_Object (**get_func
) (Lisp_Object
, const unsigned char *, int);
3766 *put_func
= xpm_put_color_table_h
;
3767 *get_func
= xpm_get_color_table_h
;
3768 return make_hash_table (Qequal
, make_number (DEFAULT_HASH_SIZE
),
3769 make_float (DEFAULT_REHASH_SIZE
),
3770 make_float (DEFAULT_REHASH_THRESHOLD
),
3775 xpm_put_color_table_h (color_table
, chars_start
, chars_len
, color
)
3776 Lisp_Object color_table
;
3777 const unsigned char *chars_start
;
3781 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
3783 Lisp_Object chars
= make_unibyte_string (chars_start
, chars_len
);
3785 hash_lookup (table
, chars
, &hash_code
);
3786 hash_put (table
, chars
, color
, hash_code
);
3790 xpm_get_color_table_h (color_table
, chars_start
, chars_len
)
3791 Lisp_Object color_table
;
3792 const unsigned char *chars_start
;
3795 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
3796 int i
= hash_lookup (table
, make_unibyte_string (chars_start
, chars_len
),
3799 return i
>= 0 ? HASH_VALUE (table
, i
) : Qnil
;
3802 enum xpm_color_key
{
3810 static const char xpm_color_key_strings
[][4] = {"s", "m", "g4", "g", "c"};
3813 xpm_str_to_color_key (s
)
3819 i
< sizeof xpm_color_key_strings
/ sizeof xpm_color_key_strings
[0];
3821 if (strcmp (xpm_color_key_strings
[i
], s
) == 0)
3827 xpm_load_image (f
, img
, contents
, end
)
3830 const unsigned char *contents
, *end
;
3832 const unsigned char *s
= contents
, *beg
, *str
;
3833 unsigned char buffer
[BUFSIZ
];
3834 int width
, height
, x
, y
;
3835 int num_colors
, chars_per_pixel
;
3837 void (*put_color_table
) (Lisp_Object
, const unsigned char *, int, Lisp_Object
);
3838 Lisp_Object (*get_color_table
) (Lisp_Object
, const unsigned char *, int);
3839 Lisp_Object frame
, color_symbols
, color_table
;
3840 int best_key
, have_mask
= 0;
3841 XImagePtr ximg
= NULL
, mask_img
= NULL
;
3844 LA1 = xpm_scan (&s, end, &beg, &len)
3846 #define expect(TOKEN) \
3847 if (LA1 != (TOKEN)) \
3852 #define expect_ident(IDENT) \
3853 if (LA1 == XPM_TK_IDENT \
3854 && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
3859 if (!(end
- s
>= 9 && memcmp (s
, "/* XPM */", 9) == 0))
3863 expect_ident ("static");
3864 expect_ident ("char");
3866 expect (XPM_TK_IDENT
);
3871 expect (XPM_TK_STRING
);
3874 memcpy (buffer
, beg
, len
);
3876 if (sscanf (buffer
, "%d %d %d %d", &width
, &height
,
3877 &num_colors
, &chars_per_pixel
) != 4
3878 || width
<= 0 || height
<= 0
3879 || num_colors
<= 0 || chars_per_pixel
<= 0)
3882 if (!check_image_size (f
, width
, height
))
3884 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
3890 XSETFRAME (frame
, f
);
3891 if (!NILP (Fxw_display_color_p (frame
)))
3892 best_key
= XPM_COLOR_KEY_C
;
3893 else if (!NILP (Fx_display_grayscale_p (frame
)))
3894 best_key
= (XFASTINT (Fx_display_planes (frame
)) > 2
3895 ? XPM_COLOR_KEY_G
: XPM_COLOR_KEY_G4
);
3897 best_key
= XPM_COLOR_KEY_M
;
3899 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
3900 if (chars_per_pixel
== 1)
3901 color_table
= xpm_make_color_table_v (&put_color_table
,
3904 color_table
= xpm_make_color_table_h (&put_color_table
,
3907 while (num_colors
-- > 0)
3909 unsigned char *color
, *max_color
;
3910 int key
, next_key
, max_key
= 0;
3911 Lisp_Object symbol_color
= Qnil
, color_val
;
3914 expect (XPM_TK_STRING
);
3915 if (len
<= chars_per_pixel
|| len
>= BUFSIZ
+ chars_per_pixel
)
3917 memcpy (buffer
, beg
+ chars_per_pixel
, len
- chars_per_pixel
);
3918 buffer
[len
- chars_per_pixel
] = '\0';
3920 str
= strtok (buffer
, " \t");
3923 key
= xpm_str_to_color_key (str
);
3928 color
= strtok (NULL
, " \t");
3932 while ((str
= strtok (NULL
, " \t")) != NULL
)
3934 next_key
= xpm_str_to_color_key (str
);
3937 color
[strlen (color
)] = ' ';
3940 if (key
== XPM_COLOR_KEY_S
)
3942 if (NILP (symbol_color
))
3943 symbol_color
= build_string (color
);
3945 else if (max_key
< key
&& key
<= best_key
)
3955 if (!NILP (color_symbols
) && !NILP (symbol_color
))
3957 Lisp_Object specified_color
= Fassoc (symbol_color
, color_symbols
);
3959 if (CONSP (specified_color
) && STRINGP (XCDR (specified_color
)))
3961 if (xstrcasecmp (SDATA (XCDR (specified_color
)), "None") == 0)
3963 else if (x_defined_color (f
, SDATA (XCDR (specified_color
)),
3965 color_val
= make_number (cdef
.pixel
);
3968 if (NILP (color_val
) && max_key
> 0)
3970 if (xstrcasecmp (max_color
, "None") == 0)
3972 else if (x_defined_color (f
, max_color
, &cdef
, 0))
3973 color_val
= make_number (cdef
.pixel
);
3975 if (!NILP (color_val
))
3976 (*put_color_table
) (color_table
, beg
, chars_per_pixel
, color_val
);
3981 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
3982 &ximg
, &img
->pixmap
)
3984 || !x_create_x_image_and_pixmap (f
, width
, height
, 1,
3985 &mask_img
, &img
->mask
)
3989 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
3993 for (y
= 0; y
< height
; y
++)
3995 expect (XPM_TK_STRING
);
3997 if (len
< width
* chars_per_pixel
)
3999 for (x
= 0; x
< width
; x
++, str
+= chars_per_pixel
)
4001 Lisp_Object color_val
=
4002 (*get_color_table
) (color_table
, str
, chars_per_pixel
);
4004 XPutPixel (ximg
, x
, y
,
4005 (INTEGERP (color_val
) ? XINT (color_val
)
4006 : FRAME_FOREGROUND_PIXEL (f
)));
4008 XPutPixel (mask_img
, x
, y
,
4009 (!EQ (color_val
, Qt
) ? PIX_MASK_DRAW
4010 : (have_mask
= 1, PIX_MASK_RETAIN
)));
4012 if (EQ (color_val
, Qt
))
4013 ns_set_alpha (ximg
, x
, y
, 0);
4021 img
->height
= height
;
4023 /* Maybe fill in the background field while we have ximg handy. */
4024 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
4025 IMAGE_BACKGROUND (img
, f
, ximg
);
4027 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
4028 x_destroy_x_image (ximg
);
4032 /* Fill in the background_transparent field while we have the
4034 image_background_transparent (img
, f
, mask_img
);
4036 x_put_x_image (f
, mask_img
, img
->mask
, width
, height
);
4037 x_destroy_x_image (mask_img
);
4041 x_destroy_x_image (mask_img
);
4042 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4043 img
->mask
= NO_PIXMAP
;
4049 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
4051 x_destroy_x_image (ximg
);
4052 x_destroy_x_image (mask_img
);
4053 x_clear_image (f
, img
);
4067 Lisp_Object file_name
;
4069 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4070 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
4071 if (STRINGP (file_name
))
4074 unsigned char *contents
;
4076 struct gcpro gcpro1
;
4078 file
= x_find_image_file (file_name
);
4080 if (!STRINGP (file
))
4082 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
4087 contents
= slurp_file (SDATA (file
), &size
);
4088 if (contents
== NULL
)
4090 image_error ("Error loading XPM image `%s'", img
->spec
, Qnil
);
4095 success_p
= xpm_load_image (f
, img
, contents
, contents
+ size
);
4103 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
4104 success_p
= xpm_load_image (f
, img
, SDATA (data
),
4105 SDATA (data
) + SBYTES (data
));
4111 #endif /* HAVE_NS && !HAVE_XPM */
4115 /***********************************************************************
4117 ***********************************************************************/
4119 #ifdef COLOR_TABLE_SUPPORT
4121 /* An entry in the color table mapping an RGB color to a pixel color. */
4126 unsigned long pixel
;
4128 /* Next in color table collision list. */
4129 struct ct_color
*next
;
4132 /* The bucket vector size to use. Must be prime. */
4136 /* Value is a hash of the RGB color given by R, G, and B. */
4138 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
4140 /* The color hash table. */
4142 struct ct_color
**ct_table
;
4144 /* Number of entries in the color table. */
4146 int ct_colors_allocated
;
4148 /* Initialize the color table. */
4151 init_color_table (void)
4153 int size
= CT_SIZE
* sizeof (*ct_table
);
4154 ct_table
= (struct ct_color
**) xmalloc (size
);
4155 memset (ct_table
, 0, size
);
4156 ct_colors_allocated
= 0;
4160 /* Free memory associated with the color table. */
4163 free_color_table (void)
4166 struct ct_color
*p
, *next
;
4168 for (i
= 0; i
< CT_SIZE
; ++i
)
4169 for (p
= ct_table
[i
]; p
; p
= next
)
4180 /* Value is a pixel color for RGB color R, G, B on frame F. If an
4181 entry for that color already is in the color table, return the
4182 pixel color of that entry. Otherwise, allocate a new color for R,
4183 G, B, and make an entry in the color table. */
4185 static unsigned long
4186 lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
)
4188 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
4189 int i
= hash
% CT_SIZE
;
4191 Display_Info
*dpyinfo
;
4193 /* Handle TrueColor visuals specially, which improves performance by
4194 two orders of magnitude. Freeing colors on TrueColor visuals is
4195 a nop, and pixel colors specify RGB values directly. See also
4196 the Xlib spec, chapter 3.1. */
4197 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
4198 if (dpyinfo
->red_bits
> 0)
4200 unsigned long pr
, pg
, pb
;
4202 /* Apply gamma-correction like normal color allocation does. */
4206 color
.red
= r
, color
.green
= g
, color
.blue
= b
;
4207 gamma_correct (f
, &color
);
4208 r
= color
.red
, g
= color
.green
, b
= color
.blue
;
4211 /* Scale down RGB values to the visual's bits per RGB, and shift
4212 them to the right position in the pixel color. Note that the
4213 original RGB values are 16-bit values, as usual in X. */
4214 pr
= (r
>> (16 - dpyinfo
->red_bits
)) << dpyinfo
->red_offset
;
4215 pg
= (g
>> (16 - dpyinfo
->green_bits
)) << dpyinfo
->green_offset
;
4216 pb
= (b
>> (16 - dpyinfo
->blue_bits
)) << dpyinfo
->blue_offset
;
4218 /* Assemble the pixel color. */
4219 return pr
| pg
| pb
;
4222 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4223 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
4229 #ifdef HAVE_X_WINDOWS
4238 cmap
= FRAME_X_COLORMAP (f
);
4239 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4242 ++ct_colors_allocated
;
4243 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4247 p
->pixel
= color
.pixel
;
4248 p
->next
= ct_table
[i
];
4252 return FRAME_FOREGROUND_PIXEL (f
);
4257 color
= PALETTERGB (r
, g
, b
);
4259 color
= RGB_TO_ULONG (r
, g
, b
);
4260 #endif /* HAVE_NTGUI */
4261 ++ct_colors_allocated
;
4262 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4267 p
->next
= ct_table
[i
];
4269 #endif /* HAVE_X_WINDOWS */
4277 /* Look up pixel color PIXEL which is used on frame F in the color
4278 table. If not already present, allocate it. Value is PIXEL. */
4280 static unsigned long
4281 lookup_pixel_color (struct frame
*f
, unsigned long pixel
)
4283 int i
= pixel
% CT_SIZE
;
4286 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4287 if (p
->pixel
== pixel
)
4296 #ifdef HAVE_X_WINDOWS
4297 cmap
= FRAME_X_COLORMAP (f
);
4298 color
.pixel
= pixel
;
4299 x_query_color (f
, &color
);
4300 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4303 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
4304 color
.pixel
= pixel
;
4305 XQueryColor (NULL
, cmap
, &color
);
4306 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4308 #endif /* HAVE_X_WINDOWS */
4312 ++ct_colors_allocated
;
4314 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4319 p
->next
= ct_table
[i
];
4323 return FRAME_FOREGROUND_PIXEL (f
);
4329 /* Value is a vector of all pixel colors contained in the color table,
4330 allocated via xmalloc. Set *N to the number of colors. */
4332 static unsigned long *
4333 colors_in_color_table (int *n
)
4337 unsigned long *colors
;
4339 if (ct_colors_allocated
== 0)
4346 colors
= (unsigned long *) xmalloc (ct_colors_allocated
4348 *n
= ct_colors_allocated
;
4350 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
4351 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4352 colors
[j
++] = p
->pixel
;
4358 #else /* COLOR_TABLE_SUPPORT */
4360 static unsigned long
4361 lookup_rgb_color (f
, r
, g
, b
)
4365 unsigned long pixel
;
4368 pixel
= PALETTERGB (r
>> 8, g
>> 8, b
>> 8);
4369 #endif /* HAVE_NTGUI */
4372 pixel
= RGB_TO_ULONG (r
>> 8, g
>> 8, b
>> 8);
4373 #endif /* HAVE_NS */
4381 #endif /* COLOR_TABLE_SUPPORT */
4384 /***********************************************************************
4386 ***********************************************************************/
4388 static XColor
*x_to_xcolors (struct frame
*, struct image
*, int);
4389 static void x_from_xcolors (struct frame
*, struct image
*, XColor
*);
4390 static void x_detect_edges (struct frame
*, struct image
*, int[9], int);
4393 static void XPutPixel (XImagePtr
, int, int, COLORREF
);
4394 #endif /* HAVE_NTGUI */
4396 /* Non-zero means draw a cross on images having `:conversion
4399 int cross_disabled_images
;
4401 /* Edge detection matrices for different edge-detection
4404 static int emboss_matrix
[9] = {
4406 2, -1, 0, /* y - 1 */
4408 0, 1, -2 /* y + 1 */
4411 static int laplace_matrix
[9] = {
4413 1, 0, 0, /* y - 1 */
4415 0, 0, -1 /* y + 1 */
4418 /* Value is the intensity of the color whose red/green/blue values
4421 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
4424 /* On frame F, return an array of XColor structures describing image
4425 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
4426 non-zero means also fill the red/green/blue members of the XColor
4427 structures. Value is a pointer to the array of XColors structures,
4428 allocated with xmalloc; it must be freed by the caller. */
4431 x_to_xcolors (struct frame
*f
, struct image
*img
, int rgb_p
)
4435 XImagePtr_or_DC ximg
;
4439 #endif /* HAVE_NTGUI */
4441 colors
= (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *colors
);
4444 /* Get the X image IMG->pixmap. */
4445 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
4446 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4448 /* Load the image into a memory device context. */
4449 hdc
= get_frame_dc (f
);
4450 ximg
= CreateCompatibleDC (hdc
);
4451 release_frame_dc (f
, hdc
);
4452 prev
= SelectObject (ximg
, img
->pixmap
);
4453 #endif /* HAVE_NTGUI */
4455 /* Fill the `pixel' members of the XColor array. I wished there
4456 were an easy and portable way to circumvent XGetPixel. */
4458 for (y
= 0; y
< img
->height
; ++y
)
4462 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
4463 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4464 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4466 x_query_colors (f
, row
, img
->width
);
4470 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4472 /* W32_TODO: palette support needed here? */
4473 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4476 p
->red
= RED16_FROM_ULONG (p
->pixel
);
4477 p
->green
= GREEN16_FROM_ULONG (p
->pixel
);
4478 p
->blue
= BLUE16_FROM_ULONG (p
->pixel
);
4481 #endif /* HAVE_X_WINDOWS */
4484 Destroy_Image (ximg
, prev
);
4491 /* Put a pixel of COLOR at position X, Y in XIMG. XIMG must have been
4492 created with CreateDIBSection, with the pointer to the bit values
4493 stored in ximg->data. */
4496 XPutPixel (ximg
, x
, y
, color
)
4501 int width
= ximg
->info
.bmiHeader
.biWidth
;
4502 int height
= ximg
->info
.bmiHeader
.biHeight
;
4503 unsigned char * pixel
;
4505 /* True color images. */
4506 if (ximg
->info
.bmiHeader
.biBitCount
== 24)
4508 int rowbytes
= width
* 3;
4509 /* Ensure scanlines are aligned on 4 byte boundaries. */
4511 rowbytes
+= 4 - (rowbytes
% 4);
4513 pixel
= ximg
->data
+ y
* rowbytes
+ x
* 3;
4514 /* Windows bitmaps are in BGR order. */
4515 *pixel
= GetBValue (color
);
4516 *(pixel
+ 1) = GetGValue (color
);
4517 *(pixel
+ 2) = GetRValue (color
);
4519 /* Monochrome images. */
4520 else if (ximg
->info
.bmiHeader
.biBitCount
== 1)
4522 int rowbytes
= width
/ 8;
4523 /* Ensure scanlines are aligned on 4 byte boundaries. */
4525 rowbytes
+= 4 - (rowbytes
% 4);
4526 pixel
= ximg
->data
+ y
* rowbytes
+ x
/ 8;
4527 /* Filter out palette info. */
4528 if (color
& 0x00ffffff)
4529 *pixel
= *pixel
| (1 << x
% 8);
4531 *pixel
= *pixel
& ~(1 << x
% 8);
4534 image_error ("XPutPixel: palette image not supported", Qnil
, Qnil
);
4537 #endif /* HAVE_NTGUI */
4539 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
4540 RGB members are set. F is the frame on which this all happens.
4541 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
4544 x_from_xcolors (struct frame
*f
, struct image
*img
, XColor
*colors
)
4547 XImagePtr oimg
= NULL
;
4551 init_color_table ();
4553 x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
4556 for (y
= 0; y
< img
->height
; ++y
)
4557 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4559 unsigned long pixel
;
4560 pixel
= lookup_rgb_color (f
, p
->red
, p
->green
, p
->blue
);
4561 XPutPixel (oimg
, x
, y
, pixel
);
4565 x_clear_image_1 (f
, img
, 1, 0, 1);
4567 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
4568 x_destroy_x_image (oimg
);
4569 img
->pixmap
= pixmap
;
4570 #ifdef COLOR_TABLE_SUPPORT
4571 img
->colors
= colors_in_color_table (&img
->ncolors
);
4572 free_color_table ();
4573 #endif /* COLOR_TABLE_SUPPORT */
4577 /* On frame F, perform edge-detection on image IMG.
4579 MATRIX is a nine-element array specifying the transformation
4580 matrix. See emboss_matrix for an example.
4582 COLOR_ADJUST is a color adjustment added to each pixel of the
4586 x_detect_edges (struct frame
*f
, struct image
*img
, int *matrix
, int color_adjust
)
4588 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4592 for (i
= sum
= 0; i
< 9; ++i
)
4593 sum
+= eabs (matrix
[i
]);
4595 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
4597 new = (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *new);
4599 for (y
= 0; y
< img
->height
; ++y
)
4601 p
= COLOR (new, 0, y
);
4602 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4603 p
= COLOR (new, img
->width
- 1, y
);
4604 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4607 for (x
= 1; x
< img
->width
- 1; ++x
)
4609 p
= COLOR (new, x
, 0);
4610 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4611 p
= COLOR (new, x
, img
->height
- 1);
4612 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4615 for (y
= 1; y
< img
->height
- 1; ++y
)
4617 p
= COLOR (new, 1, y
);
4619 for (x
= 1; x
< img
->width
- 1; ++x
, ++p
)
4621 int r
, g
, b
, y1
, x1
;
4624 for (y1
= y
- 1; y1
< y
+ 2; ++y1
)
4625 for (x1
= x
- 1; x1
< x
+ 2; ++x1
, ++i
)
4628 XColor
*t
= COLOR (colors
, x1
, y1
);
4629 r
+= matrix
[i
] * t
->red
;
4630 g
+= matrix
[i
] * t
->green
;
4631 b
+= matrix
[i
] * t
->blue
;
4634 r
= (r
/ sum
+ color_adjust
) & 0xffff;
4635 g
= (g
/ sum
+ color_adjust
) & 0xffff;
4636 b
= (b
/ sum
+ color_adjust
) & 0xffff;
4637 p
->red
= p
->green
= p
->blue
= COLOR_INTENSITY (r
, g
, b
);
4642 x_from_xcolors (f
, img
, new);
4648 /* Perform the pre-defined `emboss' edge-detection on image IMG
4652 x_emboss (struct frame
*f
, struct image
*img
)
4654 x_detect_edges (f
, img
, emboss_matrix
, 0xffff / 2);
4658 /* Transform image IMG which is used on frame F with a Laplace
4659 edge-detection algorithm. The result is an image that can be used
4660 to draw disabled buttons, for example. */
4663 x_laplace (struct frame
*f
, struct image
*img
)
4665 x_detect_edges (f
, img
, laplace_matrix
, 45000);
4669 /* Perform edge-detection on image IMG on frame F, with specified
4670 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
4672 MATRIX must be either
4674 - a list of at least 9 numbers in row-major form
4675 - a vector of at least 9 numbers
4677 COLOR_ADJUST nil means use a default; otherwise it must be a
4681 x_edge_detection (struct frame
*f
, struct image
*img
, Lisp_Object matrix
,
4682 Lisp_Object color_adjust
)
4690 i
< 9 && CONSP (matrix
) && NUMBERP (XCAR (matrix
));
4691 ++i
, matrix
= XCDR (matrix
))
4692 trans
[i
] = XFLOATINT (XCAR (matrix
));
4694 else if (VECTORP (matrix
) && ASIZE (matrix
) >= 9)
4696 for (i
= 0; i
< 9 && NUMBERP (AREF (matrix
, i
)); ++i
)
4697 trans
[i
] = XFLOATINT (AREF (matrix
, i
));
4700 if (NILP (color_adjust
))
4701 color_adjust
= make_number (0xffff / 2);
4703 if (i
== 9 && NUMBERP (color_adjust
))
4704 x_detect_edges (f
, img
, trans
, (int) XFLOATINT (color_adjust
));
4708 /* Transform image IMG on frame F so that it looks disabled. */
4711 x_disable_image (struct frame
*f
, struct image
*img
)
4713 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
4715 int n_planes
= dpyinfo
->n_planes
* dpyinfo
->n_cbits
;
4717 int n_planes
= dpyinfo
->n_planes
;
4718 #endif /* HAVE_NTGUI */
4722 /* Color (or grayscale). Convert to gray, and equalize. Just
4723 drawing such images with a stipple can look very odd, so
4724 we're using this method instead. */
4725 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4727 const int h
= 15000;
4728 const int l
= 30000;
4730 for (p
= colors
, end
= colors
+ img
->width
* img
->height
;
4734 int i
= COLOR_INTENSITY (p
->red
, p
->green
, p
->blue
);
4735 int i2
= (0xffff - h
- l
) * i
/ 0xffff + l
;
4736 p
->red
= p
->green
= p
->blue
= i2
;
4739 x_from_xcolors (f
, img
, colors
);
4742 /* Draw a cross over the disabled image, if we must or if we
4744 if (n_planes
< 2 || cross_disabled_images
)
4747 Display
*dpy
= FRAME_X_DISPLAY (f
);
4750 #ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
4752 #define MaskForeground(f) WHITE_PIX_DEFAULT (f)
4754 gc
= XCreateGC (dpy
, img
->pixmap
, 0, NULL
);
4755 XSetForeground (dpy
, gc
, BLACK_PIX_DEFAULT (f
));
4756 XDrawLine (dpy
, img
->pixmap
, gc
, 0, 0,
4757 img
->width
- 1, img
->height
- 1);
4758 XDrawLine (dpy
, img
->pixmap
, gc
, 0, img
->height
- 1,
4764 gc
= XCreateGC (dpy
, img
->mask
, 0, NULL
);
4765 XSetForeground (dpy
, gc
, MaskForeground (f
));
4766 XDrawLine (dpy
, img
->mask
, gc
, 0, 0,
4767 img
->width
- 1, img
->height
- 1);
4768 XDrawLine (dpy
, img
->mask
, gc
, 0, img
->height
- 1,
4772 #endif /* !HAVE_NS */
4777 hdc
= get_frame_dc (f
);
4778 bmpdc
= CreateCompatibleDC (hdc
);
4779 release_frame_dc (f
, hdc
);
4781 prev
= SelectObject (bmpdc
, img
->pixmap
);
4783 SetTextColor (bmpdc
, BLACK_PIX_DEFAULT (f
));
4784 MoveToEx (bmpdc
, 0, 0, NULL
);
4785 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
4786 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
4787 LineTo (bmpdc
, img
->width
- 1, 0);
4791 SelectObject (bmpdc
, img
->mask
);
4792 SetTextColor (bmpdc
, WHITE_PIX_DEFAULT (f
));
4793 MoveToEx (bmpdc
, 0, 0, NULL
);
4794 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
4795 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
4796 LineTo (bmpdc
, img
->width
- 1, 0);
4798 SelectObject (bmpdc
, prev
);
4800 #endif /* HAVE_NTGUI */
4805 /* Build a mask for image IMG which is used on frame F. FILE is the
4806 name of an image file, for error messages. HOW determines how to
4807 determine the background color of IMG. If it is a list '(R G B)',
4808 with R, G, and B being integers >= 0, take that as the color of the
4809 background. Otherwise, determine the background color of IMG
4810 heuristically. Value is non-zero if successful. */
4813 x_build_heuristic_mask (struct frame
*f
, struct image
*img
, Lisp_Object how
)
4815 XImagePtr_or_DC ximg
;
4823 #endif /* HAVE_NTGUI */
4824 int x
, y
, rc
, use_img_background
;
4825 unsigned long bg
= 0;
4829 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4830 img
->mask
= NO_PIXMAP
;
4831 img
->background_transparent_valid
= 0;
4836 /* Create an image and pixmap serving as mask. */
4837 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
4838 &mask_img
, &img
->mask
);
4841 #endif /* !HAVE_NS */
4843 /* Get the X image of IMG->pixmap. */
4844 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
, 0, 0,
4845 img
->width
, img
->height
,
4848 /* Create the bit array serving as mask. */
4849 row_width
= (img
->width
+ 7) / 8;
4850 mask_img
= xmalloc (row_width
* img
->height
);
4851 memset (mask_img
, 0, row_width
* img
->height
);
4853 /* Create a memory device context for IMG->pixmap. */
4854 frame_dc
= get_frame_dc (f
);
4855 ximg
= CreateCompatibleDC (frame_dc
);
4856 release_frame_dc (f
, frame_dc
);
4857 prev
= SelectObject (ximg
, img
->pixmap
);
4858 #endif /* HAVE_NTGUI */
4860 /* Determine the background color of ximg. If HOW is `(R G B)'
4861 take that as color. Otherwise, use the image's background color. */
4862 use_img_background
= 1;
4868 for (i
= 0; i
< 3 && CONSP (how
) && NATNUMP (XCAR (how
)); ++i
)
4870 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
4874 if (i
== 3 && NILP (how
))
4876 char color_name
[30];
4877 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
4880 0x00ffffff & /* Filter out palette info. */
4881 #endif /* HAVE_NTGUI */
4882 x_alloc_image_color (f
, img
, build_string (color_name
), 0));
4883 use_img_background
= 0;
4887 if (use_img_background
)
4888 bg
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
4890 /* Set all bits in mask_img to 1 whose color in ximg is different
4891 from the background color bg. */
4893 for (y
= 0; y
< img
->height
; ++y
)
4894 for (x
= 0; x
< img
->width
; ++x
)
4896 XPutPixel (mask_img
, x
, y
, (XGetPixel (ximg
, x
, y
) != bg
4897 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
));
4899 if (XGetPixel (ximg
, x
, y
) == bg
)
4900 ns_set_alpha (ximg
, x
, y
, 0);
4901 #endif /* HAVE_NS */
4903 /* Fill in the background_transparent field while we have the mask handy. */
4904 image_background_transparent (img
, f
, mask_img
);
4906 /* Put mask_img into img->mask. */
4907 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
4908 x_destroy_x_image (mask_img
);
4909 #endif /* !HAVE_NS */
4911 for (y
= 0; y
< img
->height
; ++y
)
4912 for (x
= 0; x
< img
->width
; ++x
)
4914 COLORREF p
= GetPixel (ximg
, x
, y
);
4916 mask_img
[y
* row_width
+ x
/ 8] |= 1 << (x
% 8);
4919 /* Create the mask image. */
4920 img
->mask
= w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
,
4922 /* Fill in the background_transparent field while we have the mask handy. */
4923 SelectObject (ximg
, img
->mask
);
4924 image_background_transparent (img
, f
, ximg
);
4926 /* Was: x_destroy_x_image ((XImagePtr )mask_img); which seems bogus ++kfs */
4928 #endif /* HAVE_NTGUI */
4930 Destroy_Image (ximg
, prev
);
4936 /***********************************************************************
4937 PBM (mono, gray, color)
4938 ***********************************************************************/
4940 static int pbm_image_p (Lisp_Object object
);
4941 static int pbm_load (struct frame
*f
, struct image
*img
);
4942 static int pbm_scan_number (unsigned char **, unsigned char *);
4944 /* The symbol `pbm' identifying images of this type. */
4948 /* Indices of image specification fields in gs_format, below. */
4950 enum pbm_keyword_index
4966 /* Vector of image_keyword structures describing the format
4967 of valid user-defined image specifications. */
4969 static const struct image_keyword pbm_format
[PBM_LAST
] =
4971 {":type", IMAGE_SYMBOL_VALUE
, 1},
4972 {":file", IMAGE_STRING_VALUE
, 0},
4973 {":data", IMAGE_STRING_VALUE
, 0},
4974 {":ascent", IMAGE_ASCENT_VALUE
, 0},
4975 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
4976 {":relief", IMAGE_INTEGER_VALUE
, 0},
4977 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4978 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4979 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4980 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
4981 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
4984 /* Structure describing the image type `pbm'. */
4986 static struct image_type pbm_type
=
4996 /* Return non-zero if OBJECT is a valid PBM image specification. */
4999 pbm_image_p (Lisp_Object object
)
5001 struct image_keyword fmt
[PBM_LAST
];
5003 memcpy (fmt
, pbm_format
, sizeof fmt
);
5005 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
))
5008 /* Must specify either :data or :file. */
5009 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
5013 /* Scan a decimal number from *S and return it. Advance *S while
5014 reading the number. END is the end of the string. Value is -1 at
5018 pbm_scan_number (unsigned char **s
, unsigned char *end
)
5020 int c
= 0, val
= -1;
5024 /* Skip white-space. */
5025 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
5030 /* Skip comment to end of line. */
5031 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
5034 else if (isdigit (c
))
5036 /* Read decimal number. */
5038 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
5039 val
= 10 * val
+ c
- '0';
5051 #if 0 /* Unused. ++kfs */
5053 /* Read FILE into memory. Value is a pointer to a buffer allocated
5054 with xmalloc holding FILE's contents. Value is null if an error
5055 occurred. *SIZE is set to the size of the file. */
5058 pbm_read_file (file
, size
)
5066 if (stat (SDATA (file
), &st
) == 0
5067 && (fp
= fopen (SDATA (file
), "rb")) != NULL
5068 && (buf
= (char *) xmalloc (st
.st_size
),
5069 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
5088 #endif /* HAVE_NTGUI */
5090 /* Load PBM image IMG for use on frame F. */
5093 pbm_load (struct frame
*f
, struct image
*img
)
5096 int width
, height
, max_color_idx
= 0;
5098 Lisp_Object file
, specified_file
;
5099 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
5100 struct gcpro gcpro1
;
5101 unsigned char *contents
= NULL
;
5102 unsigned char *end
, *p
;
5105 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5109 if (STRINGP (specified_file
))
5111 file
= x_find_image_file (specified_file
);
5112 if (!STRINGP (file
))
5114 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5119 contents
= slurp_file (SDATA (file
), &size
);
5120 if (contents
== NULL
)
5122 image_error ("Error reading `%s'", file
, Qnil
);
5128 end
= contents
+ size
;
5133 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5135 end
= p
+ SBYTES (data
);
5138 /* Check magic number. */
5139 if (end
- p
< 2 || *p
++ != 'P')
5141 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5151 raw_p
= 0, type
= PBM_MONO
;
5155 raw_p
= 0, type
= PBM_GRAY
;
5159 raw_p
= 0, type
= PBM_COLOR
;
5163 raw_p
= 1, type
= PBM_MONO
;
5167 raw_p
= 1, type
= PBM_GRAY
;
5171 raw_p
= 1, type
= PBM_COLOR
;
5175 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5179 /* Read width, height, maximum color-component. Characters
5180 starting with `#' up to the end of a line are ignored. */
5181 width
= pbm_scan_number (&p
, end
);
5182 height
= pbm_scan_number (&p
, end
);
5184 if (type
!= PBM_MONO
)
5186 max_color_idx
= pbm_scan_number (&p
, end
);
5187 if (max_color_idx
> 65535 || max_color_idx
< 0)
5189 image_error ("Unsupported maximum PBM color value", Qnil
, Qnil
);
5194 if (!check_image_size (f
, width
, height
))
5196 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
5200 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
5201 &ximg
, &img
->pixmap
))
5204 /* Initialize the color hash table. */
5205 init_color_table ();
5207 if (type
== PBM_MONO
)
5210 struct image_keyword fmt
[PBM_LAST
];
5211 unsigned long fg
= FRAME_FOREGROUND_PIXEL (f
);
5212 unsigned long bg
= FRAME_BACKGROUND_PIXEL (f
);
5214 /* Parse the image specification. */
5215 memcpy (fmt
, pbm_format
, sizeof fmt
);
5216 parse_image_spec (img
->spec
, fmt
, PBM_LAST
, Qpbm
);
5218 /* Get foreground and background colors, maybe allocate colors. */
5219 if (fmt
[PBM_FOREGROUND
].count
5220 && STRINGP (fmt
[PBM_FOREGROUND
].value
))
5221 fg
= x_alloc_image_color (f
, img
, fmt
[PBM_FOREGROUND
].value
, fg
);
5222 if (fmt
[PBM_BACKGROUND
].count
5223 && STRINGP (fmt
[PBM_BACKGROUND
].value
))
5225 bg
= x_alloc_image_color (f
, img
, fmt
[PBM_BACKGROUND
].value
, bg
);
5226 img
->background
= bg
;
5227 img
->background_valid
= 1;
5230 for (y
= 0; y
< height
; ++y
)
5231 for (x
= 0; x
< width
; ++x
)
5239 x_destroy_x_image (ximg
);
5240 x_clear_image (f
, img
);
5241 image_error ("Invalid image size in image `%s'",
5251 g
= pbm_scan_number (&p
, end
);
5253 XPutPixel (ximg
, x
, y
, g
? fg
: bg
);
5258 int expected_size
= height
* width
;
5259 if (max_color_idx
> 255)
5261 if (type
== PBM_COLOR
)
5264 if (raw_p
&& p
+ expected_size
> end
)
5266 x_destroy_x_image (ximg
);
5267 x_clear_image (f
, img
);
5268 image_error ("Invalid image size in image `%s'",
5273 for (y
= 0; y
< height
; ++y
)
5274 for (x
= 0; x
< width
; ++x
)
5278 if (type
== PBM_GRAY
&& raw_p
)
5281 if (max_color_idx
> 255)
5282 r
= g
= b
= r
* 256 + *p
++;
5284 else if (type
== PBM_GRAY
)
5285 r
= g
= b
= pbm_scan_number (&p
, end
);
5289 if (max_color_idx
> 255)
5292 if (max_color_idx
> 255)
5295 if (max_color_idx
> 255)
5300 r
= pbm_scan_number (&p
, end
);
5301 g
= pbm_scan_number (&p
, end
);
5302 b
= pbm_scan_number (&p
, end
);
5305 if (r
< 0 || g
< 0 || b
< 0)
5307 x_destroy_x_image (ximg
);
5308 image_error ("Invalid pixel value in image `%s'",
5313 /* RGB values are now in the range 0..max_color_idx.
5314 Scale this to the range 0..0xffff supported by X. */
5315 r
= (double) r
* 65535 / max_color_idx
;
5316 g
= (double) g
* 65535 / max_color_idx
;
5317 b
= (double) b
* 65535 / max_color_idx
;
5318 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
5322 #ifdef COLOR_TABLE_SUPPORT
5323 /* Store in IMG->colors the colors allocated for the image, and
5324 free the color table. */
5325 img
->colors
= colors_in_color_table (&img
->ncolors
);
5326 free_color_table ();
5327 #endif /* COLOR_TABLE_SUPPORT */
5330 img
->height
= height
;
5332 /* Maybe fill in the background field while we have ximg handy. */
5334 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
5335 /* Casting avoids a GCC warning. */
5336 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
5338 /* Put the image into a pixmap. */
5339 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
5340 x_destroy_x_image (ximg
);
5342 /* X and W32 versions did it here, MAC version above. ++kfs
5344 img->height = height; */
5352 /***********************************************************************
5354 ***********************************************************************/
5356 #if defined (HAVE_PNG) || defined (HAVE_NS)
5358 /* Function prototypes. */
5360 static int png_image_p (Lisp_Object object
);
5361 static int png_load (struct frame
*f
, struct image
*img
);
5363 /* The symbol `png' identifying images of this type. */
5367 /* Indices of image specification fields in png_format, below. */
5369 enum png_keyword_index
5384 /* Vector of image_keyword structures describing the format
5385 of valid user-defined image specifications. */
5387 static const struct image_keyword png_format
[PNG_LAST
] =
5389 {":type", IMAGE_SYMBOL_VALUE
, 1},
5390 {":data", IMAGE_STRING_VALUE
, 0},
5391 {":file", IMAGE_STRING_VALUE
, 0},
5392 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5393 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5394 {":relief", IMAGE_INTEGER_VALUE
, 0},
5395 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5396 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5397 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5398 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
5401 /* Structure describing the image type `png'. */
5403 static struct image_type png_type
=
5412 /* Return non-zero if OBJECT is a valid PNG image specification. */
5415 png_image_p (Lisp_Object object
)
5417 struct image_keyword fmt
[PNG_LAST
];
5418 memcpy (fmt
, png_format
, sizeof fmt
);
5420 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
5423 /* Must specify either the :data or :file keyword. */
5424 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
5427 #endif /* HAVE_PNG || HAVE_NS */
5433 /* PNG library details. */
5435 DEF_IMGLIB_FN (png_get_io_ptr
);
5436 DEF_IMGLIB_FN (png_sig_cmp
);
5437 DEF_IMGLIB_FN (png_create_read_struct
);
5438 DEF_IMGLIB_FN (png_create_info_struct
);
5439 DEF_IMGLIB_FN (png_destroy_read_struct
);
5440 DEF_IMGLIB_FN (png_set_read_fn
);
5441 DEF_IMGLIB_FN (png_set_sig_bytes
);
5442 DEF_IMGLIB_FN (png_read_info
);
5443 DEF_IMGLIB_FN (png_get_IHDR
);
5444 DEF_IMGLIB_FN (png_get_valid
);
5445 DEF_IMGLIB_FN (png_set_strip_16
);
5446 DEF_IMGLIB_FN (png_set_expand
);
5447 DEF_IMGLIB_FN (png_set_gray_to_rgb
);
5448 DEF_IMGLIB_FN (png_set_background
);
5449 DEF_IMGLIB_FN (png_get_bKGD
);
5450 DEF_IMGLIB_FN (png_read_update_info
);
5451 DEF_IMGLIB_FN (png_get_channels
);
5452 DEF_IMGLIB_FN (png_get_rowbytes
);
5453 DEF_IMGLIB_FN (png_read_image
);
5454 DEF_IMGLIB_FN (png_read_end
);
5455 DEF_IMGLIB_FN (png_error
);
5458 init_png_functions (Lisp_Object libraries
)
5462 /* Try loading libpng under probable names. */
5463 if (!(library
= w32_delayed_load (libraries
, Qpng
)))
5466 LOAD_IMGLIB_FN (library
, png_get_io_ptr
);
5467 LOAD_IMGLIB_FN (library
, png_sig_cmp
);
5468 LOAD_IMGLIB_FN (library
, png_create_read_struct
);
5469 LOAD_IMGLIB_FN (library
, png_create_info_struct
);
5470 LOAD_IMGLIB_FN (library
, png_destroy_read_struct
);
5471 LOAD_IMGLIB_FN (library
, png_set_read_fn
);
5472 LOAD_IMGLIB_FN (library
, png_set_sig_bytes
);
5473 LOAD_IMGLIB_FN (library
, png_read_info
);
5474 LOAD_IMGLIB_FN (library
, png_get_IHDR
);
5475 LOAD_IMGLIB_FN (library
, png_get_valid
);
5476 LOAD_IMGLIB_FN (library
, png_set_strip_16
);
5477 LOAD_IMGLIB_FN (library
, png_set_expand
);
5478 LOAD_IMGLIB_FN (library
, png_set_gray_to_rgb
);
5479 LOAD_IMGLIB_FN (library
, png_set_background
);
5480 LOAD_IMGLIB_FN (library
, png_get_bKGD
);
5481 LOAD_IMGLIB_FN (library
, png_read_update_info
);
5482 LOAD_IMGLIB_FN (library
, png_get_channels
);
5483 LOAD_IMGLIB_FN (library
, png_get_rowbytes
);
5484 LOAD_IMGLIB_FN (library
, png_read_image
);
5485 LOAD_IMGLIB_FN (library
, png_read_end
);
5486 LOAD_IMGLIB_FN (library
, png_error
);
5491 #define fn_png_get_io_ptr png_get_io_ptr
5492 #define fn_png_sig_cmp png_sig_cmp
5493 #define fn_png_create_read_struct png_create_read_struct
5494 #define fn_png_create_info_struct png_create_info_struct
5495 #define fn_png_destroy_read_struct png_destroy_read_struct
5496 #define fn_png_set_read_fn png_set_read_fn
5497 #define fn_png_set_sig_bytes png_set_sig_bytes
5498 #define fn_png_read_info png_read_info
5499 #define fn_png_get_IHDR png_get_IHDR
5500 #define fn_png_get_valid png_get_valid
5501 #define fn_png_set_strip_16 png_set_strip_16
5502 #define fn_png_set_expand png_set_expand
5503 #define fn_png_set_gray_to_rgb png_set_gray_to_rgb
5504 #define fn_png_set_background png_set_background
5505 #define fn_png_get_bKGD png_get_bKGD
5506 #define fn_png_read_update_info png_read_update_info
5507 #define fn_png_get_channels png_get_channels
5508 #define fn_png_get_rowbytes png_get_rowbytes
5509 #define fn_png_read_image png_read_image
5510 #define fn_png_read_end png_read_end
5511 #define fn_png_error png_error
5513 #endif /* HAVE_NTGUI */
5515 /* Error and warning handlers installed when the PNG library
5519 my_png_error (png_struct
*png_ptr
, const char *msg
)
5521 xassert (png_ptr
!= NULL
);
5522 image_error ("PNG error: %s", build_string (msg
), Qnil
);
5523 longjmp (png_ptr
->jmpbuf
, 1);
5528 my_png_warning (png_struct
*png_ptr
, const char *msg
)
5530 xassert (png_ptr
!= NULL
);
5531 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
5534 /* Memory source for PNG decoding. */
5536 struct png_memory_storage
5538 unsigned char *bytes
; /* The data */
5539 size_t len
; /* How big is it? */
5540 int index
; /* Where are we? */
5544 /* Function set as reader function when reading PNG image from memory.
5545 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5546 bytes from the input to DATA. */
5549 png_read_from_memory (png_structp png_ptr
, png_bytep data
, png_size_t length
)
5551 struct png_memory_storage
*tbr
5552 = (struct png_memory_storage
*) fn_png_get_io_ptr (png_ptr
);
5554 if (length
> tbr
->len
- tbr
->index
)
5555 fn_png_error (png_ptr
, "Read error");
5557 memcpy (data
, tbr
->bytes
+ tbr
->index
, length
);
5558 tbr
->index
= tbr
->index
+ length
;
5562 /* Function set as reader function when reading PNG image from a file.
5563 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5564 bytes from the input to DATA. */
5567 png_read_from_file (png_structp png_ptr
, png_bytep data
, png_size_t length
)
5569 FILE *fp
= (FILE *) fn_png_get_io_ptr (png_ptr
);
5571 if (fread (data
, 1, length
, fp
) < length
)
5572 fn_png_error (png_ptr
, "Read error");
5576 /* Load PNG image IMG for use on frame F. Value is non-zero if
5580 png_load (struct frame
*f
, struct image
*img
)
5582 Lisp_Object file
, specified_file
;
5583 Lisp_Object specified_data
;
5585 XImagePtr ximg
, mask_img
= NULL
;
5586 struct gcpro gcpro1
;
5587 png_struct
*png_ptr
= NULL
;
5588 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
5589 FILE *volatile fp
= NULL
;
5591 png_byte
* volatile pixels
= NULL
;
5592 png_byte
** volatile rows
= NULL
;
5593 png_uint_32 width
, height
;
5594 int bit_depth
, color_type
, interlace_type
;
5596 png_uint_32 row_bytes
;
5598 struct png_memory_storage tbr
; /* Data to be read */
5600 /* Find out what file to load. */
5601 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5602 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5606 if (NILP (specified_data
))
5608 file
= x_find_image_file (specified_file
);
5609 if (!STRINGP (file
))
5611 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5616 /* Open the image file. */
5617 fp
= fopen (SDATA (file
), "rb");
5620 image_error ("Cannot open image file `%s'", file
, Qnil
);
5625 /* Check PNG signature. */
5626 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
5627 || fn_png_sig_cmp (sig
, 0, sizeof sig
))
5629 image_error ("Not a PNG file: `%s'", file
, Qnil
);
5637 /* Read from memory. */
5638 tbr
.bytes
= SDATA (specified_data
);
5639 tbr
.len
= SBYTES (specified_data
);
5642 /* Check PNG signature. */
5643 if (tbr
.len
< sizeof sig
5644 || fn_png_sig_cmp (tbr
.bytes
, 0, sizeof sig
))
5646 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
5651 /* Need to skip past the signature. */
5652 tbr
.bytes
+= sizeof (sig
);
5655 /* Initialize read and info structs for PNG lib. Casting return
5656 value avoids a GCC warning on W32. */
5657 png_ptr
= (png_structp
)fn_png_create_read_struct (PNG_LIBPNG_VER_STRING
,
5662 if (fp
) fclose (fp
);
5667 /* Casting return value avoids a GCC warning on W32. */
5668 info_ptr
= (png_infop
)fn_png_create_info_struct (png_ptr
);
5671 fn_png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
5672 if (fp
) fclose (fp
);
5677 /* Casting return value avoids a GCC warning on W32. */
5678 end_info
= (png_infop
)fn_png_create_info_struct (png_ptr
);
5681 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
5682 if (fp
) fclose (fp
);
5687 /* Set error jump-back. We come back here when the PNG library
5688 detects an error. */
5689 if (setjmp (png_ptr
->jmpbuf
))
5693 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
5696 if (fp
) fclose (fp
);
5701 /* Read image info. */
5702 if (!NILP (specified_data
))
5703 fn_png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
5705 fn_png_set_read_fn (png_ptr
, (void *) fp
, png_read_from_file
);
5707 fn_png_set_sig_bytes (png_ptr
, sizeof sig
);
5708 fn_png_read_info (png_ptr
, info_ptr
);
5709 fn_png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
5710 &interlace_type
, NULL
, NULL
);
5712 if (!check_image_size (f
, width
, height
))
5714 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
5717 /* If image contains simply transparency data, we prefer to
5718 construct a clipping mask. */
5719 if (fn_png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
5724 /* This function is easier to write if we only have to handle
5725 one data format: RGB or RGBA with 8 bits per channel. Let's
5726 transform other formats into that format. */
5728 /* Strip more than 8 bits per channel. */
5729 if (bit_depth
== 16)
5730 fn_png_set_strip_16 (png_ptr
);
5732 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
5734 fn_png_set_expand (png_ptr
);
5736 /* Convert grayscale images to RGB. */
5737 if (color_type
== PNG_COLOR_TYPE_GRAY
5738 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
5739 fn_png_set_gray_to_rgb (png_ptr
);
5741 /* Handle alpha channel by combining the image with a background
5742 color. Do this only if a real alpha channel is supplied. For
5743 simple transparency, we prefer a clipping mask. */
5746 /* png_color_16 *image_bg; */
5747 Lisp_Object specified_bg
5748 = image_spec_value (img
->spec
, QCbackground
, NULL
);
5749 int shift
= (bit_depth
== 16) ? 0 : 8;
5751 if (STRINGP (specified_bg
))
5752 /* The user specified `:background', use that. */
5755 if (x_defined_color (f
, SDATA (specified_bg
), &color
, 0))
5757 png_color_16 user_bg
;
5759 memset (&user_bg
, 0, sizeof user_bg
);
5760 user_bg
.red
= color
.red
>> shift
;
5761 user_bg
.green
= color
.green
>> shift
;
5762 user_bg
.blue
= color
.blue
>> shift
;
5764 fn_png_set_background (png_ptr
, &user_bg
,
5765 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
5770 /* We use the current frame background, ignoring any default
5771 background color set by the image. */
5772 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
5774 png_color_16 frame_background
;
5776 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
5777 x_query_color (f
, &color
);
5779 memset (&frame_background
, 0, sizeof frame_background
);
5780 frame_background
.red
= color
.red
>> shift
;
5781 frame_background
.green
= color
.green
>> shift
;
5782 frame_background
.blue
= color
.blue
>> shift
;
5783 #endif /* HAVE_X_WINDOWS */
5785 fn_png_set_background (png_ptr
, &frame_background
,
5786 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
5790 /* Update info structure. */
5791 fn_png_read_update_info (png_ptr
, info_ptr
);
5793 /* Get number of channels. Valid values are 1 for grayscale images
5794 and images with a palette, 2 for grayscale images with transparency
5795 information (alpha channel), 3 for RGB images, and 4 for RGB
5796 images with alpha channel, i.e. RGBA. If conversions above were
5797 sufficient we should only have 3 or 4 channels here. */
5798 channels
= fn_png_get_channels (png_ptr
, info_ptr
);
5799 xassert (channels
== 3 || channels
== 4);
5801 /* Number of bytes needed for one row of the image. */
5802 row_bytes
= fn_png_get_rowbytes (png_ptr
, info_ptr
);
5804 /* Allocate memory for the image. */
5805 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
5806 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
5807 for (i
= 0; i
< height
; ++i
)
5808 rows
[i
] = pixels
+ i
* row_bytes
;
5810 /* Read the entire image. */
5811 fn_png_read_image (png_ptr
, rows
);
5812 fn_png_read_end (png_ptr
, info_ptr
);
5819 /* Create the X image and pixmap. */
5820 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
5824 /* Create an image and pixmap serving as mask if the PNG image
5825 contains an alpha channel. */
5828 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
5829 &mask_img
, &img
->mask
))
5831 x_destroy_x_image (ximg
);
5832 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
5833 img
->pixmap
= NO_PIXMAP
;
5837 /* Fill the X image and mask from PNG data. */
5838 init_color_table ();
5840 for (y
= 0; y
< height
; ++y
)
5842 png_byte
*p
= rows
[y
];
5844 for (x
= 0; x
< width
; ++x
)
5851 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
5852 /* An alpha channel, aka mask channel, associates variable
5853 transparency with an image. Where other image formats
5854 support binary transparency---fully transparent or fully
5855 opaque---PNG allows up to 254 levels of partial transparency.
5856 The PNG library implements partial transparency by combining
5857 the image with a specified background color.
5859 I'm not sure how to handle this here nicely: because the
5860 background on which the image is displayed may change, for
5861 real alpha channel support, it would be necessary to create
5862 a new image for each possible background.
5864 What I'm doing now is that a mask is created if we have
5865 boolean transparency information. Otherwise I'm using
5866 the frame's background color to combine the image with. */
5871 XPutPixel (mask_img
, x
, y
, *p
> 0 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
);
5877 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
5878 /* Set IMG's background color from the PNG image, unless the user
5882 if (fn_png_get_bKGD (png_ptr
, info_ptr
, &bg
))
5884 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
5885 img
->background_valid
= 1;
5889 #ifdef COLOR_TABLE_SUPPORT
5890 /* Remember colors allocated for this image. */
5891 img
->colors
= colors_in_color_table (&img
->ncolors
);
5892 free_color_table ();
5893 #endif /* COLOR_TABLE_SUPPORT */
5896 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
5901 img
->height
= height
;
5903 /* Maybe fill in the background field while we have ximg handy.
5904 Casting avoids a GCC warning. */
5905 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
5907 /* Put the image into the pixmap, then free the X image and its buffer. */
5908 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
5909 x_destroy_x_image (ximg
);
5911 /* Same for the mask. */
5914 /* Fill in the background_transparent field while we have the
5915 mask handy. Casting avoids a GCC warning. */
5916 image_background_transparent (img
, f
, (XImagePtr_or_DC
)mask_img
);
5918 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
5919 x_destroy_x_image (mask_img
);
5926 #else /* HAVE_PNG */
5930 png_load (struct frame
*f
, struct image
*img
)
5932 return ns_load_image(f
, img
,
5933 image_spec_value (img
->spec
, QCfile
, NULL
),
5934 image_spec_value (img
->spec
, QCdata
, NULL
));
5936 #endif /* HAVE_NS */
5939 #endif /* !HAVE_PNG */
5943 /***********************************************************************
5945 ***********************************************************************/
5947 #if defined (HAVE_JPEG) || defined (HAVE_NS)
5949 static int jpeg_image_p (Lisp_Object object
);
5950 static int jpeg_load (struct frame
*f
, struct image
*img
);
5952 /* The symbol `jpeg' identifying images of this type. */
5956 /* Indices of image specification fields in gs_format, below. */
5958 enum jpeg_keyword_index
5967 JPEG_HEURISTIC_MASK
,
5973 /* Vector of image_keyword structures describing the format
5974 of valid user-defined image specifications. */
5976 static const struct image_keyword jpeg_format
[JPEG_LAST
] =
5978 {":type", IMAGE_SYMBOL_VALUE
, 1},
5979 {":data", IMAGE_STRING_VALUE
, 0},
5980 {":file", IMAGE_STRING_VALUE
, 0},
5981 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5982 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5983 {":relief", IMAGE_INTEGER_VALUE
, 0},
5984 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5985 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5986 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5987 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
5990 /* Structure describing the image type `jpeg'. */
5992 static struct image_type jpeg_type
=
6001 /* Return non-zero if OBJECT is a valid JPEG image specification. */
6004 jpeg_image_p (Lisp_Object object
)
6006 struct image_keyword fmt
[JPEG_LAST
];
6008 memcpy (fmt
, jpeg_format
, sizeof fmt
);
6010 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
6013 /* Must specify either the :data or :file keyword. */
6014 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
6017 #endif /* HAVE_JPEG || HAVE_NS */
6021 /* Work around a warning about HAVE_STDLIB_H being redefined in
6023 #ifdef HAVE_STDLIB_H
6024 #define HAVE_STDLIB_H_1
6025 #undef HAVE_STDLIB_H
6026 #endif /* HAVE_STLIB_H */
6028 #if defined (HAVE_NTGUI) && !defined (__WIN32__)
6029 /* In older releases of the jpeg library, jpeglib.h will define boolean
6030 differently depending on __WIN32__, so make sure it is defined. */
6034 #include <jpeglib.h>
6037 #ifdef HAVE_STLIB_H_1
6038 #define HAVE_STDLIB_H 1
6043 /* JPEG library details. */
6044 DEF_IMGLIB_FN (jpeg_CreateDecompress
);
6045 DEF_IMGLIB_FN (jpeg_start_decompress
);
6046 DEF_IMGLIB_FN (jpeg_finish_decompress
);
6047 DEF_IMGLIB_FN (jpeg_destroy_decompress
);
6048 DEF_IMGLIB_FN (jpeg_read_header
);
6049 DEF_IMGLIB_FN (jpeg_read_scanlines
);
6050 DEF_IMGLIB_FN (jpeg_std_error
);
6051 DEF_IMGLIB_FN (jpeg_resync_to_restart
);
6054 init_jpeg_functions (Lisp_Object libraries
)
6058 if (!(library
= w32_delayed_load (libraries
, Qjpeg
)))
6061 LOAD_IMGLIB_FN (library
, jpeg_finish_decompress
);
6062 LOAD_IMGLIB_FN (library
, jpeg_read_scanlines
);
6063 LOAD_IMGLIB_FN (library
, jpeg_start_decompress
);
6064 LOAD_IMGLIB_FN (library
, jpeg_read_header
);
6065 LOAD_IMGLIB_FN (library
, jpeg_CreateDecompress
);
6066 LOAD_IMGLIB_FN (library
, jpeg_destroy_decompress
);
6067 LOAD_IMGLIB_FN (library
, jpeg_std_error
);
6068 LOAD_IMGLIB_FN (library
, jpeg_resync_to_restart
);
6072 /* Wrapper since we can't directly assign the function pointer
6073 to another function pointer that was declared more completely easily. */
6075 jpeg_resync_to_restart_wrapper (cinfo
, desired
)
6076 j_decompress_ptr cinfo
;
6079 return fn_jpeg_resync_to_restart (cinfo
, desired
);
6084 #define fn_jpeg_CreateDecompress(a,b,c) jpeg_create_decompress(a)
6085 #define fn_jpeg_start_decompress jpeg_start_decompress
6086 #define fn_jpeg_finish_decompress jpeg_finish_decompress
6087 #define fn_jpeg_destroy_decompress jpeg_destroy_decompress
6088 #define fn_jpeg_read_header jpeg_read_header
6089 #define fn_jpeg_read_scanlines jpeg_read_scanlines
6090 #define fn_jpeg_std_error jpeg_std_error
6091 #define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart
6093 #endif /* HAVE_NTGUI */
6095 struct my_jpeg_error_mgr
6097 struct jpeg_error_mgr pub
;
6098 jmp_buf setjmp_buffer
;
6103 my_error_exit (j_common_ptr cinfo
)
6105 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
6106 longjmp (mgr
->setjmp_buffer
, 1);
6110 /* Init source method for JPEG data source manager. Called by
6111 jpeg_read_header() before any data is actually read. See
6112 libjpeg.doc from the JPEG lib distribution. */
6115 our_common_init_source (j_decompress_ptr cinfo
)
6120 /* Method to terminate data source. Called by
6121 jpeg_finish_decompress() after all data has been processed. */
6124 our_common_term_source (j_decompress_ptr cinfo
)
6129 /* Fill input buffer method for JPEG data source manager. Called
6130 whenever more data is needed. We read the whole image in one step,
6131 so this only adds a fake end of input marker at the end. */
6133 static JOCTET our_memory_buffer
[2];
6136 our_memory_fill_input_buffer (j_decompress_ptr cinfo
)
6138 /* Insert a fake EOI marker. */
6139 struct jpeg_source_mgr
*src
= cinfo
->src
;
6141 our_memory_buffer
[0] = (JOCTET
) 0xFF;
6142 our_memory_buffer
[1] = (JOCTET
) JPEG_EOI
;
6144 src
->next_input_byte
= our_memory_buffer
;
6145 src
->bytes_in_buffer
= 2;
6150 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6151 is the JPEG data source manager. */
6154 our_memory_skip_input_data (j_decompress_ptr cinfo
, long int num_bytes
)
6156 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6160 if (num_bytes
> src
->bytes_in_buffer
)
6161 ERREXIT (cinfo
, JERR_INPUT_EOF
);
6163 src
->bytes_in_buffer
-= num_bytes
;
6164 src
->next_input_byte
+= num_bytes
;
6169 /* Set up the JPEG lib for reading an image from DATA which contains
6170 LEN bytes. CINFO is the decompression info structure created for
6171 reading the image. */
6174 jpeg_memory_src (j_decompress_ptr cinfo
, JOCTET
*data
, unsigned int len
)
6176 struct jpeg_source_mgr
*src
;
6178 if (cinfo
->src
== NULL
)
6180 /* First time for this JPEG object? */
6181 cinfo
->src
= (struct jpeg_source_mgr
*)
6182 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6183 sizeof (struct jpeg_source_mgr
));
6184 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6185 src
->next_input_byte
= data
;
6188 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6189 src
->init_source
= our_common_init_source
;
6190 src
->fill_input_buffer
= our_memory_fill_input_buffer
;
6191 src
->skip_input_data
= our_memory_skip_input_data
;
6192 src
->resync_to_restart
= jpeg_resync_to_restart_wrapper
; /* Use default method. */
6193 src
->term_source
= our_common_term_source
;
6194 src
->bytes_in_buffer
= len
;
6195 src
->next_input_byte
= data
;
6199 struct jpeg_stdio_mgr
6201 struct jpeg_source_mgr mgr
;
6208 /* Size of buffer to read JPEG from file.
6209 Not too big, as we want to use alloc_small. */
6210 #define JPEG_STDIO_BUFFER_SIZE 8192
6213 /* Fill input buffer method for JPEG data source manager. Called
6214 whenever more data is needed. The data is read from a FILE *. */
6217 our_stdio_fill_input_buffer (j_decompress_ptr cinfo
)
6219 struct jpeg_stdio_mgr
*src
;
6221 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6226 bytes
= fread (src
->buffer
, 1, JPEG_STDIO_BUFFER_SIZE
, src
->file
);
6228 src
->mgr
.bytes_in_buffer
= bytes
;
6231 WARNMS (cinfo
, JWRN_JPEG_EOF
);
6233 src
->buffer
[0] = (JOCTET
) 0xFF;
6234 src
->buffer
[1] = (JOCTET
) JPEG_EOI
;
6235 src
->mgr
.bytes_in_buffer
= 2;
6237 src
->mgr
.next_input_byte
= src
->buffer
;
6244 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6245 is the JPEG data source manager. */
6248 our_stdio_skip_input_data (j_decompress_ptr cinfo
, long int num_bytes
)
6250 struct jpeg_stdio_mgr
*src
;
6251 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6253 while (num_bytes
> 0 && !src
->finished
)
6255 if (num_bytes
<= src
->mgr
.bytes_in_buffer
)
6257 src
->mgr
.bytes_in_buffer
-= num_bytes
;
6258 src
->mgr
.next_input_byte
+= num_bytes
;
6263 num_bytes
-= src
->mgr
.bytes_in_buffer
;
6264 src
->mgr
.bytes_in_buffer
= 0;
6265 src
->mgr
.next_input_byte
= NULL
;
6267 our_stdio_fill_input_buffer (cinfo
);
6273 /* Set up the JPEG lib for reading an image from a FILE *.
6274 CINFO is the decompression info structure created for
6275 reading the image. */
6278 jpeg_file_src (j_decompress_ptr cinfo
, FILE *fp
)
6280 struct jpeg_stdio_mgr
*src
;
6282 if (cinfo
->src
!= NULL
)
6283 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6286 /* First time for this JPEG object? */
6287 cinfo
->src
= (struct jpeg_source_mgr
*)
6288 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6289 sizeof (struct jpeg_stdio_mgr
));
6290 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6291 src
->buffer
= (JOCTET
*)
6292 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6293 JPEG_STDIO_BUFFER_SIZE
);
6298 src
->mgr
.init_source
= our_common_init_source
;
6299 src
->mgr
.fill_input_buffer
= our_stdio_fill_input_buffer
;
6300 src
->mgr
.skip_input_data
= our_stdio_skip_input_data
;
6301 src
->mgr
.resync_to_restart
= jpeg_resync_to_restart_wrapper
; /* Use default method. */
6302 src
->mgr
.term_source
= our_common_term_source
;
6303 src
->mgr
.bytes_in_buffer
= 0;
6304 src
->mgr
.next_input_byte
= NULL
;
6308 /* Load image IMG for use on frame F. Patterned after example.c
6309 from the JPEG lib. */
6312 jpeg_load (struct frame
*f
, struct image
*img
)
6314 struct jpeg_decompress_struct cinfo
;
6315 struct my_jpeg_error_mgr mgr
;
6316 Lisp_Object file
, specified_file
;
6317 Lisp_Object specified_data
;
6318 FILE * volatile fp
= NULL
;
6320 int row_stride
, x
, y
;
6321 XImagePtr ximg
= NULL
;
6323 unsigned long *colors
;
6325 struct gcpro gcpro1
;
6327 /* Open the JPEG file. */
6328 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6329 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6333 if (NILP (specified_data
))
6335 file
= x_find_image_file (specified_file
);
6336 if (!STRINGP (file
))
6338 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6343 fp
= fopen (SDATA (file
), "rb");
6346 image_error ("Cannot open `%s'", file
, Qnil
);
6352 /* Customize libjpeg's error handling to call my_error_exit when an
6353 error is detected. This function will perform a longjmp.
6354 Casting return value avoids a GCC warning on W32. */
6355 cinfo
.err
= (struct jpeg_error_mgr
*)fn_jpeg_std_error (&mgr
.pub
);
6356 mgr
.pub
.error_exit
= my_error_exit
;
6358 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
6362 /* Called from my_error_exit. Display a JPEG error. */
6363 char buffer
[JMSG_LENGTH_MAX
];
6364 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
6365 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
6366 build_string (buffer
));
6369 /* Close the input file and destroy the JPEG object. */
6371 fclose ((FILE *) fp
);
6372 fn_jpeg_destroy_decompress (&cinfo
);
6374 /* If we already have an XImage, free that. */
6375 x_destroy_x_image (ximg
);
6377 /* Free pixmap and colors. */
6378 x_clear_image (f
, img
);
6384 /* Create the JPEG decompression object. Let it read from fp.
6385 Read the JPEG image header. */
6386 fn_jpeg_CreateDecompress (&cinfo
, JPEG_LIB_VERSION
, sizeof (cinfo
));
6388 if (NILP (specified_data
))
6389 jpeg_file_src (&cinfo
, (FILE *) fp
);
6391 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
6392 SBYTES (specified_data
));
6394 fn_jpeg_read_header (&cinfo
, 1);
6396 /* Customize decompression so that color quantization will be used.
6397 Start decompression. */
6398 cinfo
.quantize_colors
= 1;
6399 fn_jpeg_start_decompress (&cinfo
);
6400 width
= img
->width
= cinfo
.output_width
;
6401 height
= img
->height
= cinfo
.output_height
;
6403 if (!check_image_size (f
, width
, height
))
6405 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
6406 longjmp (mgr
.setjmp_buffer
, 2);
6409 /* Create X image and pixmap. */
6410 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
6411 longjmp (mgr
.setjmp_buffer
, 2);
6413 /* Allocate colors. When color quantization is used,
6414 cinfo.actual_number_of_colors has been set with the number of
6415 colors generated, and cinfo.colormap is a two-dimensional array
6416 of color indices in the range 0..cinfo.actual_number_of_colors.
6417 No more than 255 colors will be generated. */
6421 if (cinfo
.out_color_components
> 2)
6422 ir
= 0, ig
= 1, ib
= 2;
6423 else if (cinfo
.out_color_components
> 1)
6424 ir
= 0, ig
= 1, ib
= 0;
6426 ir
= 0, ig
= 0, ib
= 0;
6428 /* Use the color table mechanism because it handles colors that
6429 cannot be allocated nicely. Such colors will be replaced with
6430 a default color, and we don't have to care about which colors
6431 can be freed safely, and which can't. */
6432 init_color_table ();
6433 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
6436 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
6438 /* Multiply RGB values with 255 because X expects RGB values
6439 in the range 0..0xffff. */
6440 int r
= cinfo
.colormap
[ir
][i
] << 8;
6441 int g
= cinfo
.colormap
[ig
][i
] << 8;
6442 int b
= cinfo
.colormap
[ib
][i
] << 8;
6443 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
6446 #ifdef COLOR_TABLE_SUPPORT
6447 /* Remember those colors actually allocated. */
6448 img
->colors
= colors_in_color_table (&img
->ncolors
);
6449 free_color_table ();
6450 #endif /* COLOR_TABLE_SUPPORT */
6454 row_stride
= width
* cinfo
.output_components
;
6455 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
6457 for (y
= 0; y
< height
; ++y
)
6459 fn_jpeg_read_scanlines (&cinfo
, buffer
, 1);
6460 for (x
= 0; x
< cinfo
.output_width
; ++x
)
6461 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
6465 fn_jpeg_finish_decompress (&cinfo
);
6466 fn_jpeg_destroy_decompress (&cinfo
);
6468 fclose ((FILE *) fp
);
6470 /* Maybe fill in the background field while we have ximg handy. */
6471 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6472 /* Casting avoids a GCC warning. */
6473 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6475 /* Put the image into the pixmap. */
6476 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6477 x_destroy_x_image (ximg
);
6482 #else /* HAVE_JPEG */
6486 jpeg_load (struct frame
*f
, struct image
*img
)
6488 return ns_load_image (f
, img
,
6489 image_spec_value (img
->spec
, QCfile
, NULL
),
6490 image_spec_value (img
->spec
, QCdata
, NULL
));
6492 #endif /* HAVE_NS */
6494 #endif /* !HAVE_JPEG */
6498 /***********************************************************************
6500 ***********************************************************************/
6502 #if defined (HAVE_TIFF) || defined (HAVE_NS)
6504 static int tiff_image_p (Lisp_Object object
);
6505 static int tiff_load (struct frame
*f
, struct image
*img
);
6507 /* The symbol `tiff' identifying images of this type. */
6511 /* Indices of image specification fields in tiff_format, below. */
6513 enum tiff_keyword_index
6522 TIFF_HEURISTIC_MASK
,
6529 /* Vector of image_keyword structures describing the format
6530 of valid user-defined image specifications. */
6532 static const struct image_keyword tiff_format
[TIFF_LAST
] =
6534 {":type", IMAGE_SYMBOL_VALUE
, 1},
6535 {":data", IMAGE_STRING_VALUE
, 0},
6536 {":file", IMAGE_STRING_VALUE
, 0},
6537 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6538 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6539 {":relief", IMAGE_INTEGER_VALUE
, 0},
6540 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6541 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6542 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6543 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
6544 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0}
6547 /* Structure describing the image type `tiff'. */
6549 static struct image_type tiff_type
=
6558 /* Return non-zero if OBJECT is a valid TIFF image specification. */
6561 tiff_image_p (Lisp_Object object
)
6563 struct image_keyword fmt
[TIFF_LAST
];
6564 memcpy (fmt
, tiff_format
, sizeof fmt
);
6566 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
6569 /* Must specify either the :data or :file keyword. */
6570 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
6573 #endif /* HAVE_TIFF || HAVE_NS */
6581 /* TIFF library details. */
6582 DEF_IMGLIB_FN (TIFFSetErrorHandler
);
6583 DEF_IMGLIB_FN (TIFFSetWarningHandler
);
6584 DEF_IMGLIB_FN (TIFFOpen
);
6585 DEF_IMGLIB_FN (TIFFClientOpen
);
6586 DEF_IMGLIB_FN (TIFFGetField
);
6587 DEF_IMGLIB_FN (TIFFReadRGBAImage
);
6588 DEF_IMGLIB_FN (TIFFClose
);
6589 DEF_IMGLIB_FN (TIFFSetDirectory
);
6592 init_tiff_functions (Lisp_Object libraries
)
6596 if (!(library
= w32_delayed_load (libraries
, Qtiff
)))
6599 LOAD_IMGLIB_FN (library
, TIFFSetErrorHandler
);
6600 LOAD_IMGLIB_FN (library
, TIFFSetWarningHandler
);
6601 LOAD_IMGLIB_FN (library
, TIFFOpen
);
6602 LOAD_IMGLIB_FN (library
, TIFFClientOpen
);
6603 LOAD_IMGLIB_FN (library
, TIFFGetField
);
6604 LOAD_IMGLIB_FN (library
, TIFFReadRGBAImage
);
6605 LOAD_IMGLIB_FN (library
, TIFFClose
);
6606 LOAD_IMGLIB_FN (library
, TIFFSetDirectory
);
6612 #define fn_TIFFSetErrorHandler TIFFSetErrorHandler
6613 #define fn_TIFFSetWarningHandler TIFFSetWarningHandler
6614 #define fn_TIFFOpen TIFFOpen
6615 #define fn_TIFFClientOpen TIFFClientOpen
6616 #define fn_TIFFGetField TIFFGetField
6617 #define fn_TIFFReadRGBAImage TIFFReadRGBAImage
6618 #define fn_TIFFClose TIFFClose
6619 #define fn_TIFFSetDirectory TIFFSetDirectory
6620 #endif /* HAVE_NTGUI */
6623 /* Reading from a memory buffer for TIFF images Based on the PNG
6624 memory source, but we have to provide a lot of extra functions.
6627 We really only need to implement read and seek, but I am not
6628 convinced that the TIFF library is smart enough not to destroy
6629 itself if we only hand it the function pointers we need to
6634 unsigned char *bytes
;
6641 tiff_read_from_memory (thandle_t data
, tdata_t buf
, tsize_t size
)
6643 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6645 if (size
> src
->len
- src
->index
)
6647 memcpy (buf
, src
->bytes
+ src
->index
, size
);
6653 tiff_write_from_memory (thandle_t data
, tdata_t buf
, tsize_t size
)
6659 tiff_seek_in_memory (thandle_t data
, toff_t off
, int whence
)
6661 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6666 case SEEK_SET
: /* Go from beginning of source. */
6670 case SEEK_END
: /* Go from end of source. */
6671 idx
= src
->len
+ off
;
6674 case SEEK_CUR
: /* Go from current position. */
6675 idx
= src
->index
+ off
;
6678 default: /* Invalid `whence'. */
6682 if (idx
> src
->len
|| idx
< 0)
6690 tiff_close_memory (thandle_t data
)
6697 tiff_mmap_memory (thandle_t data
, tdata_t
*pbase
, toff_t
*psize
)
6699 /* It is already _IN_ memory. */
6704 tiff_unmap_memory (thandle_t data
, tdata_t base
, toff_t size
)
6706 /* We don't need to do this. */
6710 tiff_size_of_memory (thandle_t data
)
6712 return ((tiff_memory_source
*) data
)->len
;
6717 tiff_error_handler (const char *title
, const char *format
, va_list ap
)
6722 len
= sprintf (buf
, "TIFF error: %s ", title
);
6723 vsprintf (buf
+ len
, format
, ap
);
6724 add_to_log (buf
, Qnil
, Qnil
);
6729 tiff_warning_handler (const char *title
, const char *format
, va_list ap
)
6734 len
= sprintf (buf
, "TIFF warning: %s ", title
);
6735 vsprintf (buf
+ len
, format
, ap
);
6736 add_to_log (buf
, Qnil
, Qnil
);
6740 /* Load TIFF image IMG for use on frame F. Value is non-zero if
6744 tiff_load (struct frame
*f
, struct image
*img
)
6746 Lisp_Object file
, specified_file
;
6747 Lisp_Object specified_data
;
6749 int width
, height
, x
, y
, count
;
6753 struct gcpro gcpro1
;
6754 tiff_memory_source memsrc
;
6757 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6758 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6762 fn_TIFFSetErrorHandler (tiff_error_handler
);
6763 fn_TIFFSetWarningHandler (tiff_warning_handler
);
6765 if (NILP (specified_data
))
6767 /* Read from a file */
6768 file
= x_find_image_file (specified_file
);
6769 if (!STRINGP (file
))
6771 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6776 /* Try to open the image file. Casting return value avoids a
6777 GCC warning on W32. */
6778 tiff
= (TIFF
*)fn_TIFFOpen (SDATA (file
), "r");
6781 image_error ("Cannot open `%s'", file
, Qnil
);
6788 /* Memory source! */
6789 memsrc
.bytes
= SDATA (specified_data
);
6790 memsrc
.len
= SBYTES (specified_data
);
6793 /* Casting return value avoids a GCC warning on W32. */
6794 tiff
= (TIFF
*)fn_TIFFClientOpen ("memory_source", "r", &memsrc
,
6795 (TIFFReadWriteProc
) tiff_read_from_memory
,
6796 (TIFFReadWriteProc
) tiff_write_from_memory
,
6797 tiff_seek_in_memory
,
6799 tiff_size_of_memory
,
6805 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
6811 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
6812 if (INTEGERP (image
))
6814 int ino
= XFASTINT (image
);
6815 if (!fn_TIFFSetDirectory (tiff
, ino
))
6817 image_error ("Invalid image number `%s' in image `%s'",
6819 fn_TIFFClose (tiff
);
6825 /* Get width and height of the image, and allocate a raster buffer
6826 of width x height 32-bit values. */
6827 fn_TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
6828 fn_TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
6830 if (!check_image_size (f
, width
, height
))
6832 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
6833 fn_TIFFClose (tiff
);
6838 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
6840 rc
= fn_TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
6842 /* Count the number of images in the file. */
6843 for (count
= 1, rc2
= 1; rc2
; count
++)
6844 rc2
= fn_TIFFSetDirectory (tiff
, count
);
6847 img
->data
.lisp_val
= Fcons (Qcount
,
6848 Fcons (make_number (count
),
6849 img
->data
.lisp_val
));
6851 fn_TIFFClose (tiff
);
6854 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
6860 /* Create the X image and pixmap. */
6861 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
6868 /* Initialize the color table. */
6869 init_color_table ();
6871 /* Process the pixel raster. Origin is in the lower-left corner. */
6872 for (y
= 0; y
< height
; ++y
)
6874 uint32
*row
= buf
+ y
* width
;
6876 for (x
= 0; x
< width
; ++x
)
6878 uint32 abgr
= row
[x
];
6879 int r
= TIFFGetR (abgr
) << 8;
6880 int g
= TIFFGetG (abgr
) << 8;
6881 int b
= TIFFGetB (abgr
) << 8;
6882 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
6886 #ifdef COLOR_TABLE_SUPPORT
6887 /* Remember the colors allocated for the image. Free the color table. */
6888 img
->colors
= colors_in_color_table (&img
->ncolors
);
6889 free_color_table ();
6890 #endif /* COLOR_TABLE_SUPPORT */
6893 img
->height
= height
;
6895 /* Maybe fill in the background field while we have ximg handy. */
6896 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6897 /* Casting avoids a GCC warning on W32. */
6898 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6900 /* Put the image into the pixmap, then free the X image and its buffer. */
6901 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6902 x_destroy_x_image (ximg
);
6909 #else /* HAVE_TIFF */
6913 tiff_load (struct frame
*f
, struct image
*img
)
6915 return ns_load_image (f
, img
,
6916 image_spec_value (img
->spec
, QCfile
, NULL
),
6917 image_spec_value (img
->spec
, QCdata
, NULL
));
6919 #endif /* HAVE_NS */
6921 #endif /* !HAVE_TIFF */
6925 /***********************************************************************
6927 ***********************************************************************/
6929 #if defined (HAVE_GIF) || defined (HAVE_NS)
6931 static int gif_image_p (Lisp_Object object
);
6932 static int gif_load (struct frame
*f
, struct image
*img
);
6933 static void gif_clear_image (struct frame
*f
, struct image
*img
);
6935 /* The symbol `gif' identifying images of this type. */
6939 /* Indices of image specification fields in gif_format, below. */
6941 enum gif_keyword_index
6957 /* Vector of image_keyword structures describing the format
6958 of valid user-defined image specifications. */
6960 static const struct image_keyword gif_format
[GIF_LAST
] =
6962 {":type", IMAGE_SYMBOL_VALUE
, 1},
6963 {":data", IMAGE_STRING_VALUE
, 0},
6964 {":file", IMAGE_STRING_VALUE
, 0},
6965 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6966 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6967 {":relief", IMAGE_INTEGER_VALUE
, 0},
6968 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6969 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6970 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6971 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6972 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
6975 /* Structure describing the image type `gif'. */
6977 static struct image_type gif_type
=
6986 /* Free X resources of GIF image IMG which is used on frame F. */
6989 gif_clear_image (struct frame
*f
, struct image
*img
)
6991 /* IMG->data.ptr_val may contain metadata with extension data. */
6992 img
->data
.lisp_val
= Qnil
;
6993 x_clear_image (f
, img
);
6996 /* Return non-zero if OBJECT is a valid GIF image specification. */
6999 gif_image_p (Lisp_Object object
)
7001 struct image_keyword fmt
[GIF_LAST
];
7002 memcpy (fmt
, gif_format
, sizeof fmt
);
7004 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
7007 /* Must specify either the :data or :file keyword. */
7008 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
7011 #endif /* HAVE_GIF */
7015 #if defined (HAVE_NTGUI)
7016 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
7017 Undefine before redefining to avoid a preprocessor warning. */
7021 /* avoid conflict with QuickdrawText.h */
7022 #define DrawText gif_DrawText
7023 #include <gif_lib.h>
7026 #else /* HAVE_NTGUI */
7028 #include <gif_lib.h>
7030 #endif /* HAVE_NTGUI */
7035 /* GIF library details. */
7036 DEF_IMGLIB_FN (DGifCloseFile
);
7037 DEF_IMGLIB_FN (DGifSlurp
);
7038 DEF_IMGLIB_FN (DGifOpen
);
7039 DEF_IMGLIB_FN (DGifOpenFileName
);
7042 init_gif_functions (Lisp_Object libraries
)
7046 if (!(library
= w32_delayed_load (libraries
, Qgif
)))
7049 LOAD_IMGLIB_FN (library
, DGifCloseFile
);
7050 LOAD_IMGLIB_FN (library
, DGifSlurp
);
7051 LOAD_IMGLIB_FN (library
, DGifOpen
);
7052 LOAD_IMGLIB_FN (library
, DGifOpenFileName
);
7058 #define fn_DGifCloseFile DGifCloseFile
7059 #define fn_DGifSlurp DGifSlurp
7060 #define fn_DGifOpen DGifOpen
7061 #define fn_DGifOpenFileName DGifOpenFileName
7063 #endif /* HAVE_NTGUI */
7065 /* Reading a GIF image from memory
7066 Based on the PNG memory stuff to a certain extent. */
7070 unsigned char *bytes
;
7076 /* Make the current memory source available to gif_read_from_memory.
7077 It's done this way because not all versions of libungif support
7078 a UserData field in the GifFileType structure. */
7079 static gif_memory_source
*current_gif_memory_src
;
7082 gif_read_from_memory (GifFileType
*file
, GifByteType
*buf
, int len
)
7084 gif_memory_source
*src
= current_gif_memory_src
;
7086 if (len
> src
->len
- src
->index
)
7089 memcpy (buf
, src
->bytes
+ src
->index
, len
);
7095 /* Load GIF image IMG for use on frame F. Value is non-zero if
7098 static const int interlace_start
[] = {0, 4, 2, 1};
7099 static const int interlace_increment
[] = {8, 8, 4, 2};
7102 gif_load (struct frame
*f
, struct image
*img
)
7104 Lisp_Object file
, specified_file
;
7105 Lisp_Object specified_data
;
7106 int rc
, width
, height
, x
, y
, i
;
7108 ColorMapObject
*gif_color_map
;
7109 unsigned long pixel_colors
[256];
7111 struct gcpro gcpro1
;
7113 int ino
, image_height
, image_width
;
7114 gif_memory_source memsrc
;
7115 unsigned char *raster
;
7117 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7118 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7122 if (NILP (specified_data
))
7124 file
= x_find_image_file (specified_file
);
7125 if (!STRINGP (file
))
7127 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7132 /* Open the GIF file. Casting return value avoids a GCC warning
7134 gif
= (GifFileType
*)fn_DGifOpenFileName (SDATA (file
));
7137 image_error ("Cannot open `%s'", file
, Qnil
);
7144 /* Read from memory! */
7145 current_gif_memory_src
= &memsrc
;
7146 memsrc
.bytes
= SDATA (specified_data
);
7147 memsrc
.len
= SBYTES (specified_data
);
7150 /* Casting return value avoids a GCC warning on W32. */
7151 gif
= (GifFileType
*) fn_DGifOpen (&memsrc
, gif_read_from_memory
);
7154 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
7160 /* Before reading entire contents, check the declared image size. */
7161 if (!check_image_size (f
, gif
->SWidth
, gif
->SHeight
))
7163 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7164 fn_DGifCloseFile (gif
);
7169 /* Read entire contents. */
7170 rc
= fn_DGifSlurp (gif
);
7171 if (rc
== GIF_ERROR
)
7173 image_error ("Error reading `%s'", img
->spec
, Qnil
);
7174 fn_DGifCloseFile (gif
);
7179 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
7180 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
7181 if (ino
>= gif
->ImageCount
)
7183 image_error ("Invalid image number `%s' in image `%s'",
7185 fn_DGifCloseFile (gif
);
7190 img
->corners
[TOP_CORNER
] = gif
->SavedImages
[ino
].ImageDesc
.Top
;
7191 img
->corners
[LEFT_CORNER
] = gif
->SavedImages
[ino
].ImageDesc
.Left
;
7192 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
7193 img
->corners
[BOT_CORNER
] = img
->corners
[TOP_CORNER
] + image_height
;
7194 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
7195 img
->corners
[RIGHT_CORNER
] = img
->corners
[LEFT_CORNER
] + image_width
;
7197 width
= img
->width
= max (gif
->SWidth
,
7198 max (gif
->Image
.Left
+ gif
->Image
.Width
,
7199 img
->corners
[RIGHT_CORNER
]));
7200 height
= img
->height
= max (gif
->SHeight
,
7201 max (gif
->Image
.Top
+ gif
->Image
.Height
,
7202 img
->corners
[BOT_CORNER
]));
7204 if (!check_image_size (f
, width
, height
))
7206 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7207 fn_DGifCloseFile (gif
);
7212 /* Create the X image and pixmap. */
7213 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
7215 fn_DGifCloseFile (gif
);
7220 /* Allocate colors. */
7221 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
7223 gif_color_map
= gif
->SColorMap
;
7224 init_color_table ();
7225 memset (pixel_colors
, 0, sizeof pixel_colors
);
7228 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
7230 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
7231 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
7232 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
7233 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
7236 #ifdef COLOR_TABLE_SUPPORT
7237 img
->colors
= colors_in_color_table (&img
->ncolors
);
7238 free_color_table ();
7239 #endif /* COLOR_TABLE_SUPPORT */
7241 /* Clear the part of the screen image that are not covered by
7242 the image from the GIF file. Full animated GIF support
7243 requires more than can be done here (see the gif89 spec,
7244 disposal methods). Let's simply assume that the part
7245 not covered by a sub-image is in the frame's background color. */
7246 for (y
= 0; y
< img
->corners
[TOP_CORNER
]; ++y
)
7247 for (x
= 0; x
< width
; ++x
)
7248 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7250 for (y
= img
->corners
[BOT_CORNER
]; y
< height
; ++y
)
7251 for (x
= 0; x
< width
; ++x
)
7252 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7254 for (y
= img
->corners
[TOP_CORNER
]; y
< img
->corners
[BOT_CORNER
]; ++y
)
7256 for (x
= 0; x
< img
->corners
[LEFT_CORNER
]; ++x
)
7257 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7258 for (x
= img
->corners
[RIGHT_CORNER
]; x
< width
; ++x
)
7259 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7262 /* Read the GIF image into the X image. We use a local variable
7263 `raster' here because RasterBits below is a char *, and invites
7264 problems with bytes >= 0x80. */
7265 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
7267 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
7270 int row
= interlace_start
[0];
7274 for (y
= 0; y
< image_height
; y
++)
7276 if (row
>= image_height
)
7278 row
= interlace_start
[++pass
];
7279 while (row
>= image_height
)
7280 row
= interlace_start
[++pass
];
7283 for (x
= 0; x
< image_width
; x
++)
7285 int i
= raster
[(y
* image_width
) + x
];
7286 XPutPixel (ximg
, x
+ img
->corners
[LEFT_CORNER
],
7287 row
+ img
->corners
[TOP_CORNER
], pixel_colors
[i
]);
7290 row
+= interlace_increment
[pass
];
7295 for (y
= 0; y
< image_height
; ++y
)
7296 for (x
= 0; x
< image_width
; ++x
)
7298 int i
= raster
[y
* image_width
+ x
];
7299 XPutPixel (ximg
, x
+ img
->corners
[LEFT_CORNER
],
7300 y
+ img
->corners
[TOP_CORNER
], pixel_colors
[i
]);
7304 /* Save GIF image extension data for `image-metadata'.
7305 Format is (count IMAGES extension-data (FUNCTION "BYTES" ...)). */
7306 img
->data
.lisp_val
= Qnil
;
7307 if (gif
->SavedImages
[ino
].ExtensionBlockCount
> 0)
7309 ExtensionBlock
*ext
= gif
->SavedImages
[ino
].ExtensionBlocks
;
7310 for (i
= 0; i
< gif
->SavedImages
[ino
].ExtensionBlockCount
; i
++, ext
++)
7311 /* Append (... FUNCTION "BYTES") */
7312 img
->data
.lisp_val
= Fcons (make_unibyte_string (ext
->Bytes
, ext
->ByteCount
),
7313 Fcons (make_number (ext
->Function
),
7314 img
->data
.lisp_val
));
7315 img
->data
.lisp_val
= Fcons (Qextension_data
,
7316 Fcons (Fnreverse (img
->data
.lisp_val
),
7319 if (gif
->ImageCount
> 1)
7320 img
->data
.lisp_val
= Fcons (Qcount
,
7321 Fcons (make_number (gif
->ImageCount
),
7322 img
->data
.lisp_val
));
7324 fn_DGifCloseFile (gif
);
7326 /* Maybe fill in the background field while we have ximg handy. */
7327 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7328 /* Casting avoids a GCC warning. */
7329 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
7331 /* Put the image into the pixmap, then free the X image and its buffer. */
7332 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7333 x_destroy_x_image (ximg
);
7339 #else /* !HAVE_GIF */
7343 gif_load (struct frame
*f
, struct image
*img
)
7345 return ns_load_image (f
, img
,
7346 image_spec_value (img
->spec
, QCfile
, NULL
),
7347 image_spec_value (img
->spec
, QCdata
, NULL
));
7349 #endif /* HAVE_NS */
7351 #endif /* HAVE_GIF */
7355 /***********************************************************************
7357 ***********************************************************************/
7359 #if defined (HAVE_RSVG)
7361 /* Function prototypes. */
7363 static int svg_image_p (Lisp_Object object
);
7364 static int svg_load (struct frame
*f
, struct image
*img
);
7366 static int svg_load_image (struct frame
*, struct image
*,
7367 unsigned char *, unsigned int);
7369 /* The symbol `svg' identifying images of this type. */
7373 /* Indices of image specification fields in svg_format, below. */
7375 enum svg_keyword_index
7390 /* Vector of image_keyword structures describing the format
7391 of valid user-defined image specifications. */
7393 static const struct image_keyword svg_format
[SVG_LAST
] =
7395 {":type", IMAGE_SYMBOL_VALUE
, 1},
7396 {":data", IMAGE_STRING_VALUE
, 0},
7397 {":file", IMAGE_STRING_VALUE
, 0},
7398 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7399 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7400 {":relief", IMAGE_INTEGER_VALUE
, 0},
7401 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7402 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7403 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7404 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7407 /* Structure describing the image type `svg'. Its the same type of
7408 structure defined for all image formats, handled by emacs image
7409 functions. See struct image_type in dispextern.h. */
7411 static struct image_type svg_type
=
7413 /* An identifier showing that this is an image structure for the SVG format. */
7415 /* Handle to a function that can be used to identify a SVG file. */
7417 /* Handle to function used to load a SVG file. */
7419 /* Handle to function to free sresources for SVG. */
7421 /* An internal field to link to the next image type in a list of
7422 image types, will be filled in when registering the format. */
7427 /* Return non-zero if OBJECT is a valid SVG image specification. Do
7428 this by calling parse_image_spec and supplying the keywords that
7429 identify the SVG format. */
7432 svg_image_p (Lisp_Object object
)
7434 struct image_keyword fmt
[SVG_LAST
];
7435 memcpy (fmt
, svg_format
, sizeof fmt
);
7437 if (!parse_image_spec (object
, fmt
, SVG_LAST
, Qsvg
))
7440 /* Must specify either the :data or :file keyword. */
7441 return fmt
[SVG_FILE
].count
+ fmt
[SVG_DATA
].count
== 1;
7444 #include <librsvg/rsvg.h>
7448 /* SVG library functions. */
7449 DEF_IMGLIB_FN (rsvg_handle_new
);
7450 DEF_IMGLIB_FN (rsvg_handle_get_dimensions
);
7451 DEF_IMGLIB_FN (rsvg_handle_write
);
7452 DEF_IMGLIB_FN (rsvg_handle_close
);
7453 DEF_IMGLIB_FN (rsvg_handle_get_pixbuf
);
7454 DEF_IMGLIB_FN (rsvg_handle_free
);
7456 DEF_IMGLIB_FN (gdk_pixbuf_get_width
);
7457 DEF_IMGLIB_FN (gdk_pixbuf_get_height
);
7458 DEF_IMGLIB_FN (gdk_pixbuf_get_pixels
);
7459 DEF_IMGLIB_FN (gdk_pixbuf_get_rowstride
);
7460 DEF_IMGLIB_FN (gdk_pixbuf_get_colorspace
);
7461 DEF_IMGLIB_FN (gdk_pixbuf_get_n_channels
);
7462 DEF_IMGLIB_FN (gdk_pixbuf_get_has_alpha
);
7463 DEF_IMGLIB_FN (gdk_pixbuf_get_bits_per_sample
);
7465 DEF_IMGLIB_FN (g_type_init
);
7466 DEF_IMGLIB_FN (g_object_unref
);
7467 DEF_IMGLIB_FN (g_error_free
);
7469 Lisp_Object Qgdk_pixbuf
, Qglib
, Qgobject
;
7472 init_svg_functions (Lisp_Object libraries
)
7474 HMODULE library
, gdklib
, glib
, gobject
;
7476 if (!(glib
= w32_delayed_load (libraries
, Qglib
))
7477 || !(gobject
= w32_delayed_load (libraries
, Qgobject
))
7478 || !(gdklib
= w32_delayed_load (libraries
, Qgdk_pixbuf
))
7479 || !(library
= w32_delayed_load (libraries
, Qsvg
)))
7482 LOAD_IMGLIB_FN (library
, rsvg_handle_new
);
7483 LOAD_IMGLIB_FN (library
, rsvg_handle_get_dimensions
);
7484 LOAD_IMGLIB_FN (library
, rsvg_handle_write
);
7485 LOAD_IMGLIB_FN (library
, rsvg_handle_close
);
7486 LOAD_IMGLIB_FN (library
, rsvg_handle_get_pixbuf
);
7487 LOAD_IMGLIB_FN (library
, rsvg_handle_free
);
7489 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_width
);
7490 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_height
);
7491 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_pixels
);
7492 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_rowstride
);
7493 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_colorspace
);
7494 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_n_channels
);
7495 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_has_alpha
);
7496 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_bits_per_sample
);
7498 LOAD_IMGLIB_FN (gobject
, g_type_init
);
7499 LOAD_IMGLIB_FN (gobject
, g_object_unref
);
7500 LOAD_IMGLIB_FN (glib
, g_error_free
);
7506 /* The following aliases for library functions allow dynamic loading
7507 to be used on some platforms. */
7508 #define fn_rsvg_handle_new rsvg_handle_new
7509 #define fn_rsvg_handle_get_dimensions rsvg_handle_get_dimensions
7510 #define fn_rsvg_handle_write rsvg_handle_write
7511 #define fn_rsvg_handle_close rsvg_handle_close
7512 #define fn_rsvg_handle_get_pixbuf rsvg_handle_get_pixbuf
7513 #define fn_rsvg_handle_free rsvg_handle_free
7515 #define fn_gdk_pixbuf_get_width gdk_pixbuf_get_width
7516 #define fn_gdk_pixbuf_get_height gdk_pixbuf_get_height
7517 #define fn_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels
7518 #define fn_gdk_pixbuf_get_rowstride gdk_pixbuf_get_rowstride
7519 #define fn_gdk_pixbuf_get_colorspace gdk_pixbuf_get_colorspace
7520 #define fn_gdk_pixbuf_get_n_channels gdk_pixbuf_get_n_channels
7521 #define fn_gdk_pixbuf_get_has_alpha gdk_pixbuf_get_has_alpha
7522 #define fn_gdk_pixbuf_get_bits_per_sample gdk_pixbuf_get_bits_per_sample
7524 #define fn_g_type_init g_type_init
7525 #define fn_g_object_unref g_object_unref
7526 #define fn_g_error_free g_error_free
7527 #endif /* !HAVE_NTGUI */
7529 /* Load SVG image IMG for use on frame F. Value is non-zero if
7530 successful. this function will go into the svg_type structure, and
7531 the prototype thus needs to be compatible with that structure. */
7534 svg_load (struct frame
*f
, struct image
*img
)
7537 Lisp_Object file_name
;
7539 /* If IMG->spec specifies a file name, create a non-file spec from it. */
7540 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
7541 if (STRINGP (file_name
))
7544 unsigned char *contents
;
7546 struct gcpro gcpro1
;
7548 file
= x_find_image_file (file_name
);
7550 if (!STRINGP (file
))
7552 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
7557 /* Read the entire file into memory. */
7558 contents
= slurp_file (SDATA (file
), &size
);
7559 if (contents
== NULL
)
7561 image_error ("Error loading SVG image `%s'", img
->spec
, Qnil
);
7565 /* If the file was slurped into memory properly, parse it. */
7566 success_p
= svg_load_image (f
, img
, contents
, size
);
7570 /* Else its not a file, its a lisp object. Load the image from a
7571 lisp object rather than a file. */
7576 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7577 success_p
= svg_load_image (f
, img
, SDATA (data
), SBYTES (data
));
7583 /* svg_load_image is a helper function for svg_load, which does the
7584 actual loading given contents and size, apart from frame and image
7585 structures, passed from svg_load.
7587 Uses librsvg to do most of the image processing.
7589 Returns non-zero when successful. */
7591 svg_load_image (struct frame
*f
, /* Pointer to emacs frame structure. */
7592 struct image
*img
, /* Pointer to emacs image structure. */
7593 unsigned char *contents
, /* String containing the SVG XML data to be parsed. */
7594 unsigned int size
) /* Size of data in bytes. */
7596 RsvgHandle
*rsvg_handle
;
7597 RsvgDimensionData dimension_data
;
7598 GError
*error
= NULL
;
7602 const guint8
*pixels
;
7605 Lisp_Object specified_bg
;
7610 /* g_type_init is a glib function that must be called prior to using
7611 gnome type library functions. */
7613 /* Make a handle to a new rsvg object. */
7614 rsvg_handle
= (RsvgHandle
*) fn_rsvg_handle_new ();
7616 /* Parse the contents argument and fill in the rsvg_handle. */
7617 fn_rsvg_handle_write (rsvg_handle
, contents
, size
, &error
);
7618 if (error
) goto rsvg_error
;
7620 /* The parsing is complete, rsvg_handle is ready to used, close it
7621 for further writes. */
7622 fn_rsvg_handle_close (rsvg_handle
, &error
);
7623 if (error
) goto rsvg_error
;
7625 fn_rsvg_handle_get_dimensions (rsvg_handle
, &dimension_data
);
7626 if (! check_image_size (f
, dimension_data
.width
, dimension_data
.height
))
7628 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7632 /* We can now get a valid pixel buffer from the svg file, if all
7634 pixbuf
= (GdkPixbuf
*) fn_rsvg_handle_get_pixbuf (rsvg_handle
);
7635 if (!pixbuf
) goto rsvg_error
;
7636 fn_g_object_unref (rsvg_handle
);
7638 /* Extract some meta data from the svg handle. */
7639 width
= fn_gdk_pixbuf_get_width (pixbuf
);
7640 height
= fn_gdk_pixbuf_get_height (pixbuf
);
7641 pixels
= (const guint8
*) fn_gdk_pixbuf_get_pixels (pixbuf
);
7642 rowstride
= fn_gdk_pixbuf_get_rowstride (pixbuf
);
7644 /* Validate the svg meta data. */
7645 eassert (fn_gdk_pixbuf_get_colorspace (pixbuf
) == GDK_COLORSPACE_RGB
);
7646 eassert (fn_gdk_pixbuf_get_n_channels (pixbuf
) == 4);
7647 eassert (fn_gdk_pixbuf_get_has_alpha (pixbuf
));
7648 eassert (fn_gdk_pixbuf_get_bits_per_sample (pixbuf
) == 8);
7650 /* Try to create a x pixmap to hold the svg pixmap. */
7651 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
7653 fn_g_object_unref (pixbuf
);
7657 init_color_table ();
7659 /* Handle alpha channel by combining the image with a background
7661 specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
7662 if (!STRINGP (specified_bg
)
7663 || !x_defined_color (f
, SDATA (specified_bg
), &background
, 0))
7666 background
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
7667 x_query_color (f
, &background
);
7669 ns_query_color (FRAME_BACKGROUND_COLOR (f
), &background
, 1);
7673 /* SVG pixmaps specify transparency in the last byte, so right
7674 shift 8 bits to get rid of it, since emacs doesn't support
7676 background
.red
>>= 8;
7677 background
.green
>>= 8;
7678 background
.blue
>>= 8;
7680 /* This loop handles opacity values, since Emacs assumes
7681 non-transparent images. Each pixel must be "flattened" by
7682 calculating the resulting color, given the transparency of the
7683 pixel, and the image background color. */
7684 for (y
= 0; y
< height
; ++y
)
7686 for (x
= 0; x
< width
; ++x
)
7696 opacity
= *pixels
++;
7698 red
= ((red
* opacity
)
7699 + (background
.red
* ((1 << 8) - opacity
)));
7700 green
= ((green
* opacity
)
7701 + (background
.green
* ((1 << 8) - opacity
)));
7702 blue
= ((blue
* opacity
)
7703 + (background
.blue
* ((1 << 8) - opacity
)));
7705 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, red
, green
, blue
));
7708 pixels
+= rowstride
- 4 * width
;
7711 #ifdef COLOR_TABLE_SUPPORT
7712 /* Remember colors allocated for this image. */
7713 img
->colors
= colors_in_color_table (&img
->ncolors
);
7714 free_color_table ();
7715 #endif /* COLOR_TABLE_SUPPORT */
7717 fn_g_object_unref (pixbuf
);
7720 img
->height
= height
;
7722 /* Maybe fill in the background field while we have ximg handy.
7723 Casting avoids a GCC warning. */
7724 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
7726 /* Put the image into the pixmap, then free the X image and its
7728 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7729 x_destroy_x_image (ximg
);
7734 fn_g_object_unref (rsvg_handle
);
7735 /* FIXME: Use error->message so the user knows what is the actual
7736 problem with the image. */
7737 image_error ("Error parsing SVG image `%s'", img
->spec
, Qnil
);
7738 fn_g_error_free (error
);
7742 #endif /* defined (HAVE_RSVG) */
7747 /***********************************************************************
7749 ***********************************************************************/
7751 #ifdef HAVE_X_WINDOWS
7752 #define HAVE_GHOSTSCRIPT 1
7753 #endif /* HAVE_X_WINDOWS */
7755 /* The symbol `postscript' identifying images of this type. */
7757 Lisp_Object Qpostscript
;
7759 #ifdef HAVE_GHOSTSCRIPT
7761 static int gs_image_p (Lisp_Object object
);
7762 static int gs_load (struct frame
*f
, struct image
*img
);
7763 static void gs_clear_image (struct frame
*f
, struct image
*img
);
7765 /* Keyword symbols. */
7767 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
7769 /* Indices of image specification fields in gs_format, below. */
7771 enum gs_keyword_index
7789 /* Vector of image_keyword structures describing the format
7790 of valid user-defined image specifications. */
7792 static const struct image_keyword gs_format
[GS_LAST
] =
7794 {":type", IMAGE_SYMBOL_VALUE
, 1},
7795 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
7796 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
7797 {":file", IMAGE_STRING_VALUE
, 1},
7798 {":loader", IMAGE_FUNCTION_VALUE
, 0},
7799 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
7800 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7801 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7802 {":relief", IMAGE_INTEGER_VALUE
, 0},
7803 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7804 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7805 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7806 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7809 /* Structure describing the image type `ghostscript'. */
7811 static struct image_type gs_type
=
7821 /* Free X resources of Ghostscript image IMG which is used on frame F. */
7824 gs_clear_image (struct frame
*f
, struct image
*img
)
7826 /* IMG->data.ptr_val may contain a recorded colormap. */
7827 xfree (img
->data
.ptr_val
);
7828 x_clear_image (f
, img
);
7832 /* Return non-zero if OBJECT is a valid Ghostscript image
7836 gs_image_p (Lisp_Object object
)
7838 struct image_keyword fmt
[GS_LAST
];
7842 memcpy (fmt
, gs_format
, sizeof fmt
);
7844 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
7847 /* Bounding box must be a list or vector containing 4 integers. */
7848 tem
= fmt
[GS_BOUNDING_BOX
].value
;
7851 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
7852 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
7857 else if (VECTORP (tem
))
7859 if (XVECTOR (tem
)->size
!= 4)
7861 for (i
= 0; i
< 4; ++i
)
7862 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
7872 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
7876 gs_load (struct frame
*f
, struct image
*img
)
7879 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
7880 struct gcpro gcpro1
, gcpro2
;
7882 double in_width
, in_height
;
7883 Lisp_Object pixel_colors
= Qnil
;
7885 /* Compute pixel size of pixmap needed from the given size in the
7886 image specification. Sizes in the specification are in pt. 1 pt
7887 = 1/72 in, xdpi and ydpi are stored in the frame's X display
7889 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
7890 in_width
= XFASTINT (pt_width
) / 72.0;
7891 img
->width
= in_width
* FRAME_X_DISPLAY_INFO (f
)->resx
;
7892 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
7893 in_height
= XFASTINT (pt_height
) / 72.0;
7894 img
->height
= in_height
* FRAME_X_DISPLAY_INFO (f
)->resy
;
7896 if (!check_image_size (f
, img
->width
, img
->height
))
7898 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7902 /* Create the pixmap. */
7903 xassert (img
->pixmap
== NO_PIXMAP
);
7905 /* Only W32 version did BLOCK_INPUT here. ++kfs */
7907 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7908 img
->width
, img
->height
,
7909 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
7914 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
7918 /* Call the loader to fill the pixmap. It returns a process object
7919 if successful. We do not record_unwind_protect here because
7920 other places in redisplay like calling window scroll functions
7921 don't either. Let the Lisp loader use `unwind-protect' instead. */
7922 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
7924 sprintf (buffer
, "%lu %lu",
7925 (unsigned long) FRAME_X_WINDOW (f
),
7926 (unsigned long) img
->pixmap
);
7927 window_and_pixmap_id
= build_string (buffer
);
7929 sprintf (buffer
, "%lu %lu",
7930 FRAME_FOREGROUND_PIXEL (f
),
7931 FRAME_BACKGROUND_PIXEL (f
));
7932 pixel_colors
= build_string (buffer
);
7934 XSETFRAME (frame
, f
);
7935 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
7937 loader
= intern ("gs-load-image");
7939 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
7940 make_number (img
->width
),
7941 make_number (img
->height
),
7942 window_and_pixmap_id
,
7945 return PROCESSP (img
->data
.lisp_val
);
7949 /* Kill the Ghostscript process that was started to fill PIXMAP on
7950 frame F. Called from XTread_socket when receiving an event
7951 telling Emacs that Ghostscript has finished drawing. */
7954 x_kill_gs_process (Pixmap pixmap
, struct frame
*f
)
7956 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
7960 /* Find the image containing PIXMAP. */
7961 for (i
= 0; i
< c
->used
; ++i
)
7962 if (c
->images
[i
]->pixmap
== pixmap
)
7965 /* Should someone in between have cleared the image cache, for
7966 instance, give up. */
7970 /* Kill the GS process. We should have found PIXMAP in the image
7971 cache and its image should contain a process object. */
7973 xassert (PROCESSP (img
->data
.lisp_val
));
7974 Fkill_process (img
->data
.lisp_val
, Qnil
);
7975 img
->data
.lisp_val
= Qnil
;
7977 #if defined (HAVE_X_WINDOWS)
7979 /* On displays with a mutable colormap, figure out the colors
7980 allocated for the image by looking at the pixels of an XImage for
7982 class = FRAME_X_VISUAL (f
)->class;
7983 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
7989 /* Try to get an XImage for img->pixmep. */
7990 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
7991 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
7996 /* Initialize the color table. */
7997 init_color_table ();
7999 /* For each pixel of the image, look its color up in the
8000 color table. After having done so, the color table will
8001 contain an entry for each color used by the image. */
8002 for (y
= 0; y
< img
->height
; ++y
)
8003 for (x
= 0; x
< img
->width
; ++x
)
8005 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
8006 lookup_pixel_color (f
, pixel
);
8009 /* Record colors in the image. Free color table and XImage. */
8010 #ifdef COLOR_TABLE_SUPPORT
8011 img
->colors
= colors_in_color_table (&img
->ncolors
);
8012 free_color_table ();
8014 XDestroyImage (ximg
);
8016 #if 0 /* This doesn't seem to be the case. If we free the colors
8017 here, we get a BadAccess later in x_clear_image when
8018 freeing the colors. */
8019 /* We have allocated colors once, but Ghostscript has also
8020 allocated colors on behalf of us. So, to get the
8021 reference counts right, free them once. */
8023 x_free_colors (f
, img
->colors
, img
->ncolors
);
8027 image_error ("Cannot get X image of `%s'; colors will not be freed",
8032 #endif /* HAVE_X_WINDOWS */
8034 /* Now that we have the pixmap, compute mask and transform the
8035 image if requested. */
8037 postprocess_image (f
, img
);
8041 #endif /* HAVE_GHOSTSCRIPT */
8044 /***********************************************************************
8046 ***********************************************************************/
8050 DEFUN ("imagep", Fimagep
, Simagep
, 1, 1, 0,
8051 doc
: /* Value is non-nil if SPEC is a valid image specification. */)
8055 return valid_image_p (spec
) ? Qt
: Qnil
;
8059 DEFUN ("lookup-image", Flookup_image
, Slookup_image
, 1, 1, 0, "")
8065 if (valid_image_p (spec
))
8066 id
= lookup_image (SELECTED_FRAME (), spec
);
8069 return make_number (id
);
8072 #endif /* GLYPH_DEBUG != 0 */
8075 /***********************************************************************
8077 ***********************************************************************/
8080 /* Image types that rely on external libraries are loaded dynamically
8081 if the library is available. */
8082 #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8083 define_image_type (image_type, init_lib_fn (libraries))
8085 #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8086 define_image_type (image_type, 1)
8087 #endif /* HAVE_NTGUI */
8089 DEFUN ("init-image-library", Finit_image_library
, Sinit_image_library
, 2, 2, 0,
8090 doc
: /* Initialize image library implementing image type TYPE.
8091 Return non-nil if TYPE is a supported image type.
8093 Image types pbm and xbm are prebuilt; other types are loaded here.
8094 Libraries to load are specified in alist LIBRARIES (usually, the value
8095 of `image-library-alist', which see). */)
8097 Lisp_Object type
, libraries
;
8101 /* Don't try to reload the library. */
8102 tested
= Fassq (type
, Vimage_type_cache
);
8104 return XCDR (tested
);
8106 #if defined (HAVE_XPM) || defined (HAVE_NS)
8107 if (EQ (type
, Qxpm
))
8108 return CHECK_LIB_AVAILABLE (&xpm_type
, init_xpm_functions
, libraries
);
8111 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8112 if (EQ (type
, Qjpeg
))
8113 return CHECK_LIB_AVAILABLE (&jpeg_type
, init_jpeg_functions
, libraries
);
8116 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8117 if (EQ (type
, Qtiff
))
8118 return CHECK_LIB_AVAILABLE (&tiff_type
, init_tiff_functions
, libraries
);
8121 #if defined (HAVE_GIF) || defined (HAVE_NS)
8122 if (EQ (type
, Qgif
))
8123 return CHECK_LIB_AVAILABLE (&gif_type
, init_gif_functions
, libraries
);
8126 #if defined (HAVE_PNG) || defined (HAVE_NS)
8127 if (EQ (type
, Qpng
))
8128 return CHECK_LIB_AVAILABLE (&png_type
, init_png_functions
, libraries
);
8131 #if defined (HAVE_RSVG)
8132 if (EQ (type
, Qsvg
))
8133 return CHECK_LIB_AVAILABLE (&svg_type
, init_svg_functions
, libraries
);
8136 #ifdef HAVE_GHOSTSCRIPT
8137 if (EQ (type
, Qpostscript
))
8138 return CHECK_LIB_AVAILABLE (&gs_type
, init_gs_functions
, libraries
);
8141 /* If the type is not recognized, avoid testing it ever again. */
8142 CACHE_IMAGE_TYPE (type
, Qnil
);
8147 syms_of_image (void)
8149 extern Lisp_Object Qrisky_local_variable
; /* Syms_of_xdisp has already run. */
8151 /* Initialize this only once, since that's what we do with Vimage_types
8152 and they are supposed to be in sync. Initializing here gives correct
8153 operation on GNU/Linux of calling dump-emacs after loading some images. */
8156 /* Must be defined now becase we're going to update it below, while
8157 defining the supported image types. */
8158 DEFVAR_LISP ("image-types", &Vimage_types
,
8159 doc
: /* List of potentially supported image types.
8160 Each element of the list is a symbol for an image type, like 'jpeg or 'png.
8161 To check whether it is really supported, use `image-type-available-p'. */);
8162 Vimage_types
= Qnil
;
8164 DEFVAR_LISP ("image-library-alist", &Vimage_library_alist
,
8165 doc
: /* Alist of image types vs external libraries needed to display them.
8167 Each element is a list (IMAGE-TYPE LIBRARY...), where the car is a symbol
8168 representing a supported image type, and the rest are strings giving
8169 alternate filenames for the corresponding external libraries.
8171 Emacs tries to load the libraries in the order they appear on the
8172 list; if none is loaded, the running session of Emacs won't
8173 support the image type. Types 'pbm and 'xbm don't need to be
8174 listed; they are always supported. */);
8175 Vimage_library_alist
= Qnil
;
8176 Fput (intern_c_string ("image-library-alist"), Qrisky_local_variable
, Qt
);
8178 DEFVAR_LISP ("max-image-size", &Vmax_image_size
,
8179 doc
: /* Maximum size of images.
8180 Emacs will not load an image into memory if its pixel width or
8181 pixel height exceeds this limit.
8183 If the value is an integer, it directly specifies the maximum
8184 image height and width, measured in pixels. If it is a floating
8185 point number, it specifies the maximum image height and width
8186 as a ratio to the frame height and width. If the value is
8187 non-numeric, there is no explicit limit on the size of images. */);
8188 Vmax_image_size
= make_float (MAX_IMAGE_SIZE
);
8190 Vimage_type_cache
= Qnil
;
8191 staticpro (&Vimage_type_cache
);
8193 Qpbm
= intern_c_string ("pbm");
8195 ADD_IMAGE_TYPE (Qpbm
);
8197 Qxbm
= intern_c_string ("xbm");
8199 ADD_IMAGE_TYPE (Qxbm
);
8201 define_image_type (&xbm_type
, 1);
8202 define_image_type (&pbm_type
, 1);
8204 Qcount
= intern_c_string ("count");
8205 staticpro (&Qcount
);
8206 Qextension_data
= intern_c_string ("extension-data");
8207 staticpro (&Qextension_data
);
8209 QCascent
= intern_c_string (":ascent");
8210 staticpro (&QCascent
);
8211 QCmargin
= intern_c_string (":margin");
8212 staticpro (&QCmargin
);
8213 QCrelief
= intern_c_string (":relief");
8214 staticpro (&QCrelief
);
8215 QCconversion
= intern_c_string (":conversion");
8216 staticpro (&QCconversion
);
8217 QCcolor_symbols
= intern_c_string (":color-symbols");
8218 staticpro (&QCcolor_symbols
);
8219 QCheuristic_mask
= intern_c_string (":heuristic-mask");
8220 staticpro (&QCheuristic_mask
);
8221 QCindex
= intern_c_string (":index");
8222 staticpro (&QCindex
);
8223 QCmatrix
= intern_c_string (":matrix");
8224 staticpro (&QCmatrix
);
8225 QCcolor_adjustment
= intern_c_string (":color-adjustment");
8226 staticpro (&QCcolor_adjustment
);
8227 QCmask
= intern_c_string (":mask");
8228 staticpro (&QCmask
);
8230 Qlaplace
= intern_c_string ("laplace");
8231 staticpro (&Qlaplace
);
8232 Qemboss
= intern_c_string ("emboss");
8233 staticpro (&Qemboss
);
8234 Qedge_detection
= intern_c_string ("edge-detection");
8235 staticpro (&Qedge_detection
);
8236 Qheuristic
= intern_c_string ("heuristic");
8237 staticpro (&Qheuristic
);
8239 Qpostscript
= intern_c_string ("postscript");
8240 staticpro (&Qpostscript
);
8241 #ifdef HAVE_GHOSTSCRIPT
8242 ADD_IMAGE_TYPE (Qpostscript
);
8243 QCloader
= intern_c_string (":loader");
8244 staticpro (&QCloader
);
8245 QCbounding_box
= intern_c_string (":bounding-box");
8246 staticpro (&QCbounding_box
);
8247 QCpt_width
= intern_c_string (":pt-width");
8248 staticpro (&QCpt_width
);
8249 QCpt_height
= intern_c_string (":pt-height");
8250 staticpro (&QCpt_height
);
8251 #endif /* HAVE_GHOSTSCRIPT */
8253 #if defined (HAVE_XPM) || defined (HAVE_NS)
8254 Qxpm
= intern_c_string ("xpm");
8256 ADD_IMAGE_TYPE (Qxpm
);
8259 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8260 Qjpeg
= intern_c_string ("jpeg");
8262 ADD_IMAGE_TYPE (Qjpeg
);
8265 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8266 Qtiff
= intern_c_string ("tiff");
8268 ADD_IMAGE_TYPE (Qtiff
);
8271 #if defined (HAVE_GIF) || defined (HAVE_NS)
8272 Qgif
= intern_c_string ("gif");
8274 ADD_IMAGE_TYPE (Qgif
);
8277 #if defined (HAVE_PNG) || defined (HAVE_NS)
8278 Qpng
= intern_c_string ("png");
8280 ADD_IMAGE_TYPE (Qpng
);
8283 #if defined (HAVE_RSVG)
8284 Qsvg
= intern_c_string ("svg");
8286 ADD_IMAGE_TYPE (Qsvg
);
8288 /* Other libraries used directly by svg code. */
8289 Qgdk_pixbuf
= intern_c_string ("gdk-pixbuf");
8290 staticpro (&Qgdk_pixbuf
);
8291 Qglib
= intern_c_string ("glib");
8293 Qgobject
= intern_c_string ("gobject");
8294 staticpro (&Qgobject
);
8295 #endif /* HAVE_NTGUI */
8296 #endif /* HAVE_RSVG */
8298 defsubr (&Sinit_image_library
);
8299 defsubr (&Sclear_image_cache
);
8300 defsubr (&Simage_flush
);
8301 defsubr (&Simage_size
);
8302 defsubr (&Simage_mask_p
);
8303 defsubr (&Simage_metadata
);
8307 defsubr (&Slookup_image
);
8310 DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images
,
8311 doc
: /* Non-nil means always draw a cross over disabled images.
8312 Disabled images are those having a `:conversion disabled' property.
8313 A cross is always drawn on black & white displays. */);
8314 cross_disabled_images
= 0;
8316 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
8317 doc
: /* List of directories to search for window system bitmap files. */);
8318 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
8320 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
8321 doc
: /* Maximum time after which images are removed from the cache.
8322 When an image has not been displayed this many seconds, Emacs
8323 automatically removes it from the image cache. If the cache contains
8324 a large number of images, the actual eviction time may be shorter.
8325 The value can also be nil, meaning the cache is never cleared.
8327 The function `clear-image-cache' disregards this variable. */);
8328 Vimage_cache_eviction_delay
= make_number (300);
8336 /* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9
8337 (do not change this comment) */