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, 2011
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
);
98 /* Version of libpng that we were compiled with, or -1 if no PNG
99 support was compiled in. This is tested by w32-win.el to correctly
100 set up the alist used to search for PNG libraries. */
101 Lisp_Object Qlibpng_version
;
102 #endif /* HAVE_NTGUI */
106 #include <sys/types.h>
107 #include <sys/stat.h>
109 #undef COLOR_TABLE_SUPPORT
111 typedef struct ns_bitmap_record Bitmap_Record
;
113 #define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
116 #define RGB_PIXEL_COLOR unsigned long
119 #define PIX_MASK_RETAIN 0
120 #define PIX_MASK_DRAW 1
122 #define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO(f)->visual
123 #define x_defined_color(f, name, color_def, alloc) \
124 ns_defined_color (f, name, color_def, alloc, 0)
125 #define FRAME_X_SCREEN(f) 0
126 #define DefaultDepthOfScreen(screen) x_display_list->n_planes
130 /* Search path for bitmap files. */
132 Lisp_Object Vx_bitmap_file_path
;
135 static void x_disable_image
P_ ((struct frame
*, struct image
*));
136 static void x_edge_detection
P_ ((struct frame
*, struct image
*, Lisp_Object
,
139 static void init_color_table
P_ ((void));
140 static unsigned long lookup_rgb_color
P_ ((struct frame
*f
, int r
, int g
, int b
));
141 #ifdef COLOR_TABLE_SUPPORT
142 static void free_color_table
P_ ((void));
143 static unsigned long *colors_in_color_table
P_ ((int *n
));
144 static unsigned long lookup_pixel_color
P_ ((struct frame
*f
, unsigned long p
));
147 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
148 id, which is just an int that this section returns. Bitmaps are
149 reference counted so they can be shared among frames.
151 Bitmap indices are guaranteed to be > 0, so a negative number can
152 be used to indicate no bitmap.
154 If you use x_create_bitmap_from_data, then you must keep track of
155 the bitmaps yourself. That is, creating a bitmap from the same
156 data more than once will not be caught. */
160 XGetImage (Display
*display
, Pixmap pixmap
, int x
, int y
,
161 unsigned int width
, unsigned int height
,
162 unsigned long plane_mask
, int format
)
164 /* TODO: not sure what this function is supposed to do.. */
165 ns_retain_object(pixmap
);
169 /* use with imgs created by ns_image_for_XPM */
171 XGetPixel (XImagePtr ximage
, int x
, int y
)
173 return ns_get_pixel(ximage
, x
, y
);
176 /* use with imgs created by ns_image_for_XPM; alpha set to 1;
177 pixel is assumed to be in form RGB */
179 XPutPixel (XImagePtr ximage
, int x
, int y
, unsigned long pixel
)
181 ns_put_pixel(ximage
, x
, y
, pixel
);
186 /* Functions to access the contents of a bitmap, given an id. */
189 x_bitmap_height (f
, id
)
193 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
197 x_bitmap_width (f
, id
)
201 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
204 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
206 x_bitmap_pixmap (f
, id
)
210 return (int) FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
214 #ifdef HAVE_X_WINDOWS
216 x_bitmap_mask (f
, id
)
220 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].mask
;
224 /* Allocate a new bitmap record. Returns index of new record. */
227 x_allocate_bitmap_record (f
)
230 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
233 if (dpyinfo
->bitmaps
== NULL
)
235 dpyinfo
->bitmaps_size
= 10;
237 = (Bitmap_Record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (Bitmap_Record
));
238 dpyinfo
->bitmaps_last
= 1;
242 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
243 return ++dpyinfo
->bitmaps_last
;
245 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
246 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
249 dpyinfo
->bitmaps_size
*= 2;
251 = (Bitmap_Record
*) xrealloc (dpyinfo
->bitmaps
,
252 dpyinfo
->bitmaps_size
* sizeof (Bitmap_Record
));
253 return ++dpyinfo
->bitmaps_last
;
256 /* Add one reference to the reference count of the bitmap with id ID. */
259 x_reference_bitmap (f
, id
)
263 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
266 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
269 x_create_bitmap_from_data (f
, bits
, width
, height
)
272 unsigned int width
, height
;
274 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
277 #ifdef HAVE_X_WINDOWS
279 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
280 bits
, width
, height
);
283 #endif /* HAVE_X_WINDOWS */
287 bitmap
= CreateBitmap (width
, height
,
288 FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_planes
,
289 FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_cbits
,
293 #endif /* HAVE_NTGUI */
296 void *bitmap
= ns_image_from_XBM(bits
, width
, height
);
301 id
= x_allocate_bitmap_record (f
);
304 dpyinfo
->bitmaps
[id
- 1].img
= bitmap
;
305 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
308 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
309 dpyinfo
->bitmaps
[id
- 1].height
= height
;
310 dpyinfo
->bitmaps
[id
- 1].width
= width
;
311 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
313 #ifdef HAVE_X_WINDOWS
314 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
315 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
316 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
317 #endif /* HAVE_X_WINDOWS */
320 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
321 dpyinfo
->bitmaps
[id
- 1].hinst
= NULL
;
322 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
323 #endif /* HAVE_NTGUI */
328 /* Create bitmap from file FILE for frame F. */
331 x_create_bitmap_from_file (f
, file
)
335 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
338 return -1; /* W32_TODO : bitmap support */
339 #endif /* HAVE_NTGUI */
343 void *bitmap
= ns_image_from_file(file
);
349 id
= x_allocate_bitmap_record (f
);
350 dpyinfo
->bitmaps
[id
- 1].img
= bitmap
;
351 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
352 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (SBYTES (file
) + 1);
353 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
354 dpyinfo
->bitmaps
[id
- 1].height
= ns_image_width(bitmap
);
355 dpyinfo
->bitmaps
[id
- 1].width
= ns_image_height(bitmap
);
356 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
360 #ifdef HAVE_X_WINDOWS
361 unsigned int width
, height
;
363 int xhot
, yhot
, result
, id
;
368 /* Look for an existing bitmap with the same name. */
369 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
371 if (dpyinfo
->bitmaps
[id
].refcount
372 && dpyinfo
->bitmaps
[id
].file
373 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) SDATA (file
)))
375 ++dpyinfo
->bitmaps
[id
].refcount
;
380 /* Search bitmap-file-path for the file, if appropriate. */
381 fd
= openp (Vx_bitmap_file_path
, file
, Qnil
, &found
, Qnil
);
386 filename
= (char *) SDATA (found
);
388 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
389 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
390 if (result
!= BitmapSuccess
)
393 id
= x_allocate_bitmap_record (f
);
394 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
395 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
396 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
397 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (SBYTES (file
) + 1);
398 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
399 dpyinfo
->bitmaps
[id
- 1].height
= height
;
400 dpyinfo
->bitmaps
[id
- 1].width
= width
;
401 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
404 #endif /* HAVE_X_WINDOWS */
410 free_bitmap_record (dpyinfo
, bm
)
411 Display_Info
*dpyinfo
;
414 #ifdef HAVE_X_WINDOWS
415 XFreePixmap (dpyinfo
->display
, bm
->pixmap
);
417 XFreePixmap (dpyinfo
->display
, bm
->mask
);
418 #endif /* HAVE_X_WINDOWS */
421 DeleteObject (bm
->pixmap
);
422 #endif /* HAVE_NTGUI */
425 ns_release_object(bm
->img
);
435 /* Remove reference to bitmap with id number ID. */
438 x_destroy_bitmap (f
, id
)
442 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
446 Bitmap_Record
*bm
= &dpyinfo
->bitmaps
[id
- 1];
448 if (--bm
->refcount
== 0)
451 free_bitmap_record (dpyinfo
, bm
);
457 /* Free all the bitmaps for the display specified by DPYINFO. */
460 x_destroy_all_bitmaps (dpyinfo
)
461 Display_Info
*dpyinfo
;
464 Bitmap_Record
*bm
= dpyinfo
->bitmaps
;
466 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++, bm
++)
467 if (bm
->refcount
> 0)
468 free_bitmap_record (dpyinfo
, bm
);
470 dpyinfo
->bitmaps_last
= 0;
474 #ifdef HAVE_X_WINDOWS
476 /* Useful functions defined in the section
477 `Image type independent image structures' below. */
479 static unsigned long four_corners_best
P_ ((XImagePtr ximg
,
482 unsigned long height
));
484 static int x_create_x_image_and_pixmap
P_ ((struct frame
*f
, int width
, int height
,
485 int depth
, XImagePtr
*ximg
,
488 static void x_destroy_x_image
P_ ((XImagePtr ximg
));
491 /* Create a mask of a bitmap. Note is this not a perfect mask.
492 It's nicer with some borders in this context */
495 x_create_bitmap_mask (f
, id
)
500 XImagePtr ximg
, mask_img
;
501 unsigned long width
, height
;
504 unsigned long x
, y
, xp
, xm
, yp
, ym
;
507 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
512 pixmap
= x_bitmap_pixmap (f
, id
);
513 width
= x_bitmap_width (f
, id
);
514 height
= x_bitmap_height (f
, id
);
517 ximg
= XGetImage (FRAME_X_DISPLAY (f
), pixmap
, 0, 0, width
, height
,
526 result
= x_create_x_image_and_pixmap (f
, width
, height
, 1, &mask_img
, &mask
);
531 XDestroyImage (ximg
);
535 bg
= four_corners_best (ximg
, NULL
, width
, height
);
537 for (y
= 0; y
< ximg
->height
; ++y
)
539 for (x
= 0; x
< ximg
->width
; ++x
)
541 xp
= x
!= ximg
->width
- 1 ? x
+ 1 : 0;
542 xm
= x
!= 0 ? x
- 1 : ximg
->width
- 1;
543 yp
= y
!= ximg
->height
- 1 ? y
+ 1 : 0;
544 ym
= y
!= 0 ? y
- 1 : ximg
->height
- 1;
545 if (XGetPixel (ximg
, x
, y
) == bg
546 && XGetPixel (ximg
, x
, yp
) == bg
547 && XGetPixel (ximg
, x
, ym
) == bg
548 && XGetPixel (ximg
, xp
, y
) == bg
549 && XGetPixel (ximg
, xp
, yp
) == bg
550 && XGetPixel (ximg
, xp
, ym
) == bg
551 && XGetPixel (ximg
, xm
, y
) == bg
552 && XGetPixel (ximg
, xm
, yp
) == bg
553 && XGetPixel (ximg
, xm
, ym
) == bg
)
554 XPutPixel (mask_img
, x
, y
, 0);
556 XPutPixel (mask_img
, x
, y
, 1);
560 xassert (interrupt_input_blocked
);
561 gc
= XCreateGC (FRAME_X_DISPLAY (f
), mask
, 0, NULL
);
562 XPutImage (FRAME_X_DISPLAY (f
), mask
, gc
, mask_img
, 0, 0, 0, 0,
564 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
566 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
567 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
569 XDestroyImage (ximg
);
570 x_destroy_x_image (mask_img
);
575 #endif /* HAVE_X_WINDOWS */
578 /***********************************************************************
580 ***********************************************************************/
582 /* Value is the number of elements of vector VECTOR. */
584 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
586 /* List of supported image types. Use define_image_type to add new
587 types. Use lookup_image_type to find a type for a given symbol. */
589 static struct image_type
*image_types
;
591 /* A list of symbols, one for each supported image type. */
593 Lisp_Object Vimage_types
;
595 /* An alist of image types and libraries that implement the type. */
597 Lisp_Object Vimage_library_alist
;
599 /* Cache for delayed-loading image types. */
601 static Lisp_Object Vimage_type_cache
;
603 /* The symbol `xbm' which is used as the type symbol for XBM images. */
609 extern Lisp_Object QCwidth
, QCheight
, QCforeground
, QCbackground
, QCfile
;
610 extern Lisp_Object QCdata
, QCtype
;
611 extern Lisp_Object Qcenter
;
612 Lisp_Object QCascent
, QCmargin
, QCrelief
, Qcount
;
613 Lisp_Object QCconversion
, QCcolor_symbols
, QCheuristic_mask
;
614 Lisp_Object QCindex
, QCmatrix
, QCcolor_adjustment
, QCmask
;
618 Lisp_Object Qlaplace
, Qemboss
, Qedge_detection
, Qheuristic
;
620 /* Time in seconds after which images should be removed from the cache
623 Lisp_Object Vimage_cache_eviction_delay
;
625 /* Function prototypes. */
627 static Lisp_Object define_image_type
P_ ((struct image_type
*type
, int loaded
));
628 static struct image_type
*lookup_image_type
P_ ((Lisp_Object symbol
));
629 static void image_error
P_ ((char *format
, Lisp_Object
, Lisp_Object
));
630 static void x_laplace
P_ ((struct frame
*, struct image
*));
631 static void x_emboss
P_ ((struct frame
*, struct image
*));
632 static int x_build_heuristic_mask
P_ ((struct frame
*, struct image
*,
635 #define CACHE_IMAGE_TYPE(type, status) \
636 do { Vimage_type_cache = Fcons (Fcons (type, status), Vimage_type_cache); } while (0)
638 #define ADD_IMAGE_TYPE(type) \
639 do { Vimage_types = Fcons (type, Vimage_types); } while (0)
641 /* Define a new image type from TYPE. This adds a copy of TYPE to
642 image_types and caches the loading status of TYPE. */
645 define_image_type (type
, loaded
)
646 struct image_type
*type
;
655 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
656 The initialized data segment is read-only. */
657 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
658 bcopy (type
, p
, sizeof *p
);
659 p
->next
= image_types
;
664 CACHE_IMAGE_TYPE (*type
->type
, success
);
669 /* Look up image type SYMBOL, and return a pointer to its image_type
670 structure. Value is null if SYMBOL is not a known image type. */
672 static INLINE
struct image_type
*
673 lookup_image_type (symbol
)
676 struct image_type
*type
;
678 /* We must initialize the image-type if it hasn't been already. */
679 if (NILP (Finit_image_library (symbol
, Vimage_library_alist
)))
680 return 0; /* unimplemented */
682 for (type
= image_types
; type
; type
= type
->next
)
683 if (EQ (symbol
, *type
->type
))
690 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
691 valid image specification is a list whose car is the symbol
692 `image', and whose rest is a property list. The property list must
693 contain a value for key `:type'. That value must be the name of a
694 supported image type. The rest of the property list depends on the
698 valid_image_p (object
)
707 for (tem
= XCDR (object
); CONSP (tem
); tem
= XCDR (tem
))
708 if (EQ (XCAR (tem
), QCtype
))
711 if (CONSP (tem
) && SYMBOLP (XCAR (tem
)))
713 struct image_type
*type
;
714 type
= lookup_image_type (XCAR (tem
));
716 valid_p
= type
->valid_p (object
);
727 /* Log error message with format string FORMAT and argument ARG.
728 Signaling an error, e.g. when an image cannot be loaded, is not a
729 good idea because this would interrupt redisplay, and the error
730 message display would lead to another redisplay. This function
731 therefore simply displays a message. */
734 image_error (format
, arg1
, arg2
)
736 Lisp_Object arg1
, arg2
;
738 add_to_log (format
, arg1
, arg2
);
743 /***********************************************************************
745 ***********************************************************************/
747 enum image_value_type
749 IMAGE_DONT_CHECK_VALUE_TYPE
,
751 IMAGE_STRING_OR_NIL_VALUE
,
753 IMAGE_POSITIVE_INTEGER_VALUE
,
754 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
755 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
758 IMAGE_FUNCTION_VALUE
,
763 /* Structure used when parsing image specifications. */
767 /* Name of keyword. */
770 /* The type of value allowed. */
771 enum image_value_type type
;
773 /* Non-zero means key must be present. */
776 /* Used to recognize duplicate keywords in a property list. */
779 /* The value that was found. */
784 static int parse_image_spec
P_ ((Lisp_Object
, struct image_keyword
*,
786 static Lisp_Object image_spec_value
P_ ((Lisp_Object
, Lisp_Object
, int *));
789 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
790 has the format (image KEYWORD VALUE ...). One of the keyword/
791 value pairs must be `:type TYPE'. KEYWORDS is a vector of
792 image_keywords structures of size NKEYWORDS describing other
793 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
796 parse_image_spec (spec
, keywords
, nkeywords
, type
)
798 struct image_keyword
*keywords
;
809 while (CONSP (plist
))
811 Lisp_Object key
, value
;
813 /* First element of a pair must be a symbol. */
815 plist
= XCDR (plist
);
819 /* There must follow a value. */
822 value
= XCAR (plist
);
823 plist
= XCDR (plist
);
825 /* Find key in KEYWORDS. Error if not found. */
826 for (i
= 0; i
< nkeywords
; ++i
)
827 if (strcmp (keywords
[i
].name
, SDATA (SYMBOL_NAME (key
))) == 0)
833 /* Record that we recognized the keyword. If a keywords
834 was found more than once, it's an error. */
835 keywords
[i
].value
= value
;
838 if (keywords
[i
].count
> 1)
841 /* Check type of value against allowed type. */
842 switch (keywords
[i
].type
)
844 case IMAGE_STRING_VALUE
:
845 if (!STRINGP (value
))
849 case IMAGE_STRING_OR_NIL_VALUE
:
850 if (!STRINGP (value
) && !NILP (value
))
854 case IMAGE_SYMBOL_VALUE
:
855 if (!SYMBOLP (value
))
859 case IMAGE_POSITIVE_INTEGER_VALUE
:
860 if (!INTEGERP (value
) || XINT (value
) <= 0)
864 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
865 if (INTEGERP (value
) && XINT (value
) >= 0)
868 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
869 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
873 case IMAGE_ASCENT_VALUE
:
874 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
876 else if (INTEGERP (value
)
878 && XINT (value
) <= 100)
882 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
883 if (!INTEGERP (value
) || XINT (value
) < 0)
887 case IMAGE_DONT_CHECK_VALUE_TYPE
:
890 case IMAGE_FUNCTION_VALUE
:
891 value
= indirect_function (value
);
894 || (CONSP (value
) && EQ (XCAR (value
), Qlambda
)))
898 case IMAGE_NUMBER_VALUE
:
899 if (!INTEGERP (value
) && !FLOATP (value
))
903 case IMAGE_INTEGER_VALUE
:
904 if (!INTEGERP (value
))
908 case IMAGE_BOOL_VALUE
:
909 if (!NILP (value
) && !EQ (value
, Qt
))
918 if (EQ (key
, QCtype
) && !EQ (type
, value
))
922 /* Check that all mandatory fields are present. */
923 for (i
= 0; i
< nkeywords
; ++i
)
924 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
931 /* Return the value of KEY in image specification SPEC. Value is nil
932 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
933 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
936 image_spec_value (spec
, key
, found
)
937 Lisp_Object spec
, key
;
942 xassert (valid_image_p (spec
));
944 for (tail
= XCDR (spec
);
945 CONSP (tail
) && CONSP (XCDR (tail
));
946 tail
= XCDR (XCDR (tail
)))
948 if (EQ (XCAR (tail
), key
))
952 return XCAR (XCDR (tail
));
962 DEFUN ("image-size", Fimage_size
, Simage_size
, 1, 3, 0,
963 doc
: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
964 PIXELS non-nil means return the size in pixels, otherwise return the
965 size in canonical character units.
966 FRAME is the frame on which the image will be displayed. FRAME nil
967 or omitted means use the selected frame. */)
968 (spec
, pixels
, frame
)
969 Lisp_Object spec
, pixels
, frame
;
974 if (valid_image_p (spec
))
976 struct frame
*f
= check_x_frame (frame
);
977 int id
= lookup_image (f
, spec
);
978 struct image
*img
= IMAGE_FROM_ID (f
, id
);
979 int width
= img
->width
+ 2 * img
->hmargin
;
980 int height
= img
->height
+ 2 * img
->vmargin
;
983 size
= Fcons (make_float ((double) width
/ FRAME_COLUMN_WIDTH (f
)),
984 make_float ((double) height
/ FRAME_LINE_HEIGHT (f
)));
986 size
= Fcons (make_number (width
), make_number (height
));
989 error ("Invalid image specification");
995 DEFUN ("image-mask-p", Fimage_mask_p
, Simage_mask_p
, 1, 2, 0,
996 doc
: /* Return t if image SPEC has a mask bitmap.
997 FRAME is the frame on which the image will be displayed. FRAME nil
998 or omitted means use the selected frame. */)
1000 Lisp_Object spec
, frame
;
1005 if (valid_image_p (spec
))
1007 struct frame
*f
= check_x_frame (frame
);
1008 int id
= lookup_image (f
, spec
);
1009 struct image
*img
= IMAGE_FROM_ID (f
, id
);
1014 error ("Invalid image specification");
1019 DEFUN ("image-extension-data", Fimage_extension_data
, Simage_extension_data
, 1, 2, 0,
1020 doc
: /* Return extension data for image SPEC.
1021 FRAME is the frame on which the image will be displayed. FRAME nil
1022 or omitted means use the selected frame. */)
1024 Lisp_Object spec
, frame
;
1029 if (valid_image_p (spec
))
1031 struct frame
*f
= check_x_frame (frame
);
1032 int id
= lookup_image (f
, spec
);
1033 struct image
*img
= IMAGE_FROM_ID (f
, id
);
1034 ext
= img
->data
.lisp_val
;
1041 /***********************************************************************
1042 Image type independent image structures
1043 ***********************************************************************/
1045 static struct image
*make_image
P_ ((Lisp_Object spec
, unsigned hash
));
1046 static void free_image
P_ ((struct frame
*f
, struct image
*img
));
1047 static int check_image_size
P_ ((struct frame
*f
, int width
, int height
));
1049 #define MAX_IMAGE_SIZE 6.0
1050 Lisp_Object Vmax_image_size
;
1052 /* Allocate and return a new image structure for image specification
1053 SPEC. SPEC has a hash value of HASH. */
1055 static struct image
*
1056 make_image (spec
, hash
)
1060 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
1061 Lisp_Object file
= image_spec_value (spec
, QCfile
, NULL
);
1063 xassert (valid_image_p (spec
));
1064 bzero (img
, sizeof *img
);
1065 img
->dependencies
= NILP (file
) ? Qnil
: list1 (file
);
1066 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
1067 xassert (img
->type
!= NULL
);
1069 img
->data
.lisp_val
= Qnil
;
1070 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
1072 img
->corners
[BOT_CORNER
] = -1; /* Full image */
1077 /* Free image IMG which was used on frame F, including its resources. */
1086 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1088 /* Remove IMG from the hash table of its cache. */
1090 img
->prev
->next
= img
->next
;
1092 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
1095 img
->next
->prev
= img
->prev
;
1097 c
->images
[img
->id
] = NULL
;
1099 /* Free resources, then free IMG. */
1100 img
->type
->free (f
, img
);
1105 /* Return 1 if the given widths and heights are valid for display;
1106 otherwise, return 0. */
1109 check_image_size (f
, width
, height
)
1116 if (width
<= 0 || height
<= 0)
1119 if (INTEGERP (Vmax_image_size
))
1120 w
= h
= XINT (Vmax_image_size
);
1121 else if (FLOATP (Vmax_image_size
))
1125 w
= FRAME_PIXEL_WIDTH (f
);
1126 h
= FRAME_PIXEL_HEIGHT (f
);
1129 w
= h
= 1024; /* Arbitrary size for unknown frame. */
1130 w
= (int) (XFLOAT_DATA (Vmax_image_size
) * w
);
1131 h
= (int) (XFLOAT_DATA (Vmax_image_size
) * h
);
1136 return (width
<= w
&& height
<= h
);
1139 /* Prepare image IMG for display on frame F. Must be called before
1140 drawing an image. */
1143 prepare_image_for_display (f
, img
)
1149 /* We're about to display IMG, so set its timestamp to `now'. */
1151 img
->timestamp
= EMACS_SECS (t
);
1153 /* If IMG doesn't have a pixmap yet, load it now, using the image
1154 type dependent loader function. */
1155 if (img
->pixmap
== NO_PIXMAP
&& !img
->load_failed_p
)
1156 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
1161 /* Value is the number of pixels for the ascent of image IMG when
1162 drawn in face FACE. */
1165 image_ascent (img
, face
, slice
)
1168 struct glyph_slice
*slice
;
1173 if (slice
->height
== img
->height
)
1174 height
= img
->height
+ img
->vmargin
;
1175 else if (slice
->y
== 0)
1176 height
= slice
->height
+ img
->vmargin
;
1178 height
= slice
->height
;
1180 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
1185 /* W32 specific version. Why?. ++kfs */
1186 ascent
= height
/ 2 - (FONT_DESCENT (face
->font
)
1187 - FONT_BASE (face
->font
)) / 2;
1189 /* This expression is arranged so that if the image can't be
1190 exactly centered, it will be moved slightly up. This is
1191 because a typical font is `top-heavy' (due to the presence
1192 uppercase letters), so the image placement should err towards
1193 being top-heavy too. It also just generally looks better. */
1194 ascent
= (height
+ FONT_BASE(face
->font
)
1195 - FONT_DESCENT(face
->font
) + 1) / 2;
1196 #endif /* HAVE_NTGUI */
1199 ascent
= height
/ 2;
1202 ascent
= (int) (height
* img
->ascent
/ 100.0);
1208 /* Image background colors. */
1210 /* Find the "best" corner color of a bitmap.
1211 On W32, XIMG is assumed to a device context with the bitmap selected. */
1213 static RGB_PIXEL_COLOR
1214 four_corners_best (ximg
, corners
, width
, height
)
1215 XImagePtr_or_DC ximg
;
1217 unsigned long width
, height
;
1219 RGB_PIXEL_COLOR corner_pixels
[4], best
;
1222 if (corners
&& corners
[BOT_CORNER
] >= 0)
1224 /* Get the colors at the corner_pixels of ximg. */
1225 corner_pixels
[0] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[TOP_CORNER
]);
1226 corner_pixels
[1] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[TOP_CORNER
]);
1227 corner_pixels
[2] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[BOT_CORNER
] - 1);
1228 corner_pixels
[3] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[BOT_CORNER
] - 1);
1232 /* Get the colors at the corner_pixels of ximg. */
1233 corner_pixels
[0] = GET_PIXEL (ximg
, 0, 0);
1234 corner_pixels
[1] = GET_PIXEL (ximg
, width
- 1, 0);
1235 corner_pixels
[2] = GET_PIXEL (ximg
, width
- 1, height
- 1);
1236 corner_pixels
[3] = GET_PIXEL (ximg
, 0, height
- 1);
1238 /* Choose the most frequently found color as background. */
1239 for (i
= best_count
= 0; i
< 4; ++i
)
1243 for (j
= n
= 0; j
< 4; ++j
)
1244 if (corner_pixels
[i
] == corner_pixels
[j
])
1248 best
= corner_pixels
[i
], best_count
= n
;
1254 /* Portability macros */
1258 #define Destroy_Image(img_dc, prev) \
1259 do { SelectObject (img_dc, prev); DeleteDC (img_dc); } while (0)
1261 #define Free_Pixmap(display, pixmap) \
1262 DeleteObject (pixmap)
1264 #elif defined (HAVE_NS)
1266 #define Destroy_Image(ximg, dummy) \
1267 ns_release_object(ximg)
1269 #define Free_Pixmap(display, pixmap) \
1270 ns_release_object(pixmap)
1274 #define Destroy_Image(ximg, dummy) \
1275 XDestroyImage (ximg)
1277 #define Free_Pixmap(display, pixmap) \
1278 XFreePixmap (display, pixmap)
1280 #endif /* !HAVE_NTGUI && !HAVE_NS */
1283 /* Return the `background' field of IMG. If IMG doesn't have one yet,
1284 it is guessed heuristically. If non-zero, XIMG is an existing
1285 XImage object (or device context with the image selected on W32) to
1286 use for the heuristic. */
1289 image_background (img
, f
, ximg
)
1292 XImagePtr_or_DC ximg
;
1294 if (! img
->background_valid
)
1295 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1297 int free_ximg
= !ximg
;
1300 #endif /* HAVE_NTGUI */
1305 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
1306 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
1308 HDC frame_dc
= get_frame_dc (f
);
1309 ximg
= CreateCompatibleDC (frame_dc
);
1310 release_frame_dc (f
, frame_dc
);
1311 prev
= SelectObject (ximg
, img
->pixmap
);
1312 #endif /* !HAVE_NTGUI */
1315 img
->background
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
1318 Destroy_Image (ximg
, prev
);
1320 img
->background_valid
= 1;
1323 return img
->background
;
1326 /* Return the `background_transparent' field of IMG. If IMG doesn't
1327 have one yet, it is guessed heuristically. If non-zero, MASK is an
1328 existing XImage object to use for the heuristic. */
1331 image_background_transparent (img
, f
, mask
)
1334 XImagePtr_or_DC mask
;
1336 if (! img
->background_transparent_valid
)
1337 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1341 int free_mask
= !mask
;
1344 #endif /* HAVE_NTGUI */
1349 mask
= XGetImage (FRAME_X_DISPLAY (f
), img
->mask
,
1350 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
1352 HDC frame_dc
= get_frame_dc (f
);
1353 mask
= CreateCompatibleDC (frame_dc
);
1354 release_frame_dc (f
, frame_dc
);
1355 prev
= SelectObject (mask
, img
->mask
);
1356 #endif /* HAVE_NTGUI */
1359 img
->background_transparent
1360 = (four_corners_best (mask
, img
->corners
, img
->width
, img
->height
) == PIX_MASK_RETAIN
);
1363 Destroy_Image (mask
, prev
);
1366 img
->background_transparent
= 0;
1368 img
->background_transparent_valid
= 1;
1371 return img
->background_transparent
;
1375 /***********************************************************************
1376 Helper functions for X image types
1377 ***********************************************************************/
1379 static void x_clear_image_1
P_ ((struct frame
*, struct image
*, int,
1381 static void x_clear_image
P_ ((struct frame
*f
, struct image
*img
));
1382 static unsigned long x_alloc_image_color
P_ ((struct frame
*f
,
1384 Lisp_Object color_name
,
1385 unsigned long dflt
));
1388 /* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
1389 free the pixmap if any. MASK_P non-zero means clear the mask
1390 pixmap if any. COLORS_P non-zero means free colors allocated for
1391 the image, if any. */
1394 x_clear_image_1 (f
, img
, pixmap_p
, mask_p
, colors_p
)
1397 int pixmap_p
, mask_p
, colors_p
;
1399 if (pixmap_p
&& img
->pixmap
)
1401 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
1402 img
->pixmap
= NO_PIXMAP
;
1403 /* NOTE (HAVE_NS): background color is NOT an indexed color! */
1404 img
->background_valid
= 0;
1407 if (mask_p
&& img
->mask
)
1409 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
1410 img
->mask
= NO_PIXMAP
;
1411 img
->background_transparent_valid
= 0;
1414 if (colors_p
&& img
->ncolors
)
1416 /* W32_TODO: color table support. */
1417 #ifdef HAVE_X_WINDOWS
1418 x_free_colors (f
, img
->colors
, img
->ncolors
);
1419 #endif /* HAVE_X_WINDOWS */
1420 xfree (img
->colors
);
1427 /* Free X resources of image IMG which is used on frame F. */
1430 x_clear_image (f
, img
)
1435 x_clear_image_1 (f
, img
, 1, 1, 1);
1440 /* Allocate color COLOR_NAME for image IMG on frame F. If color
1441 cannot be allocated, use DFLT. Add a newly allocated color to
1442 IMG->colors, so that it can be freed again. Value is the pixel
1445 static unsigned long
1446 x_alloc_image_color (f
, img
, color_name
, dflt
)
1449 Lisp_Object color_name
;
1453 unsigned long result
;
1455 xassert (STRINGP (color_name
));
1457 if (x_defined_color (f
, SDATA (color_name
), &color
, 1))
1459 /* This isn't called frequently so we get away with simply
1460 reallocating the color vector to the needed size, here. */
1463 (unsigned long *) xrealloc (img
->colors
,
1464 img
->ncolors
* sizeof *img
->colors
);
1465 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
1466 result
= color
.pixel
;
1476 /***********************************************************************
1478 ***********************************************************************/
1480 static struct image
*search_image_cache
P_ ((struct frame
*, Lisp_Object
, unsigned));
1481 static void cache_image
P_ ((struct frame
*f
, struct image
*img
));
1482 static void postprocess_image
P_ ((struct frame
*, struct image
*));
1484 /* Return a new, initialized image cache that is allocated from the
1485 heap. Call free_image_cache to free an image cache. */
1487 struct image_cache
*
1490 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
1493 bzero (c
, sizeof *c
);
1495 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
1496 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
1497 c
->buckets
= (struct image
**) xmalloc (size
);
1498 bzero (c
->buckets
, size
);
1503 /* Find an image matching SPEC in the cache, and return it. If no
1504 image is found, return NULL. */
1505 static struct image
*
1506 search_image_cache (f
, spec
, hash
)
1512 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1513 int i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1515 if (!c
) return NULL
;
1517 /* If the image spec does not specify a background color, the cached
1518 image must have the same background color as the current frame.
1519 The foreground color must also match, for the sake of monochrome
1522 In fact, we could ignore the foreground color matching condition
1523 for color images, or if the image spec specifies :foreground;
1524 similarly we could ignore the background color matching condition
1525 for formats that don't use transparency (such as jpeg), or if the
1526 image spec specifies :background. However, the extra memory
1527 usage is probably negligible in practice, so we don't bother. */
1529 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
1530 if (img
->hash
== hash
1531 && !NILP (Fequal (img
->spec
, spec
))
1532 && img
->frame_foreground
== FRAME_FOREGROUND_PIXEL (f
)
1533 && img
->frame_background
== FRAME_BACKGROUND_PIXEL (f
))
1539 /* Search frame F for an image with spec SPEC, and free it. */
1542 uncache_image (f
, spec
)
1546 struct image
*img
= search_image_cache (f
, spec
, sxhash (spec
, 0));
1549 free_image (f
, img
);
1550 /* As display glyphs may still be referring to the image ID, we
1551 must garbage the frame (Bug#6426). */
1552 SET_FRAME_GARBAGED (f
);
1557 /* Free image cache of frame F. Be aware that X frames share images
1561 free_image_cache (f
)
1564 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1569 /* Cache should not be referenced by any frame when freed. */
1570 xassert (c
->refcount
== 0);
1572 for (i
= 0; i
< c
->used
; ++i
)
1573 free_image (f
, c
->images
[i
]);
1577 FRAME_IMAGE_CACHE (f
) = NULL
;
1582 /* Clear image cache of frame F. FILTER=t means free all images.
1583 FILTER=nil means clear only images that haven't been
1584 displayed for some time.
1585 Else, only free the images which have FILTER in their `dependencies'.
1586 Should be called from time to time to reduce the number of loaded images.
1587 If image-cache-eviction-delay is non-nil, this frees images in the cache
1588 which weren't displayed for at least that many seconds. */
1591 clear_image_cache (struct frame
*f
, Lisp_Object filter
)
1593 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1595 if (c
&& (!NILP (filter
) || INTEGERP (Vimage_cache_eviction_delay
)))
1602 old
= EMACS_SECS (t
) - XFASTINT (Vimage_cache_eviction_delay
);
1604 /* Block input so that we won't be interrupted by a SIGIO
1605 while being in an inconsistent state. */
1608 for (i
= nfreed
= 0; i
< c
->used
; ++i
)
1610 struct image
*img
= c
->images
[i
];
1612 && (NILP (filter
) ? img
->timestamp
< old
1614 || !NILP (Fmember (filter
, img
->dependencies
)))))
1616 free_image (f
, img
);
1621 /* We may be clearing the image cache because, for example,
1622 Emacs was iconified for a longer period of time. In that
1623 case, current matrices may still contain references to
1624 images freed above. So, clear these matrices. */
1627 Lisp_Object tail
, frame
;
1629 FOR_EACH_FRAME (tail
, frame
)
1631 struct frame
*f
= XFRAME (frame
);
1632 if (FRAME_IMAGE_CACHE (f
) == c
)
1633 clear_current_matrices (f
);
1636 ++windows_or_buffers_changed
;
1644 clear_image_caches (Lisp_Object filter
)
1646 /* FIXME: We want to do
1647 * struct terminal *t;
1648 * for (t = terminal_list; t; t = t->next_terminal)
1649 * clear_image_cache (t, filter); */
1650 Lisp_Object tail
, frame
;
1651 FOR_EACH_FRAME (tail
, frame
)
1652 if (FRAME_WINDOW_P (XFRAME (frame
)))
1653 clear_image_cache (XFRAME (frame
), filter
);
1656 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
1658 doc
: /* Clear the image cache.
1659 FILTER nil or a frame means clear all images in the selected frame.
1660 FILTER t means clear the image caches of all frames.
1661 Anything else, means only clear those images which refer to FILTER,
1662 which is then usually a filename. */)
1666 if (!(EQ (filter
, Qnil
) || FRAMEP (filter
)))
1667 clear_image_caches (filter
);
1669 clear_image_cache (check_x_frame (filter
), Qt
);
1675 DEFUN ("image-refresh", Fimage_refresh
, Simage_refresh
,
1677 doc
: /* Refresh the image with specification SPEC on frame FRAME.
1678 If SPEC specifies an image file, the displayed image is updated with
1679 the current contents of that file.
1680 FRAME nil or omitted means use the selected frame.
1681 FRAME t means refresh the image on all frames. */)
1683 Lisp_Object spec
, frame
;
1685 if (!valid_image_p (spec
))
1686 error ("Invalid image specification");
1691 FOR_EACH_FRAME (tail
, frame
)
1693 struct frame
*f
= XFRAME (frame
);
1694 if (FRAME_WINDOW_P (f
))
1695 uncache_image (f
, spec
);
1699 uncache_image (check_x_frame (frame
), spec
);
1705 /* Compute masks and transform image IMG on frame F, as specified
1706 by the image's specification, */
1709 postprocess_image (f
, img
)
1713 /* Manipulation of the image's mask. */
1716 Lisp_Object conversion
, spec
;
1721 /* `:heuristic-mask t'
1723 means build a mask heuristically.
1724 `:heuristic-mask (R G B)'
1725 `:mask (heuristic (R G B))'
1726 means build a mask from color (R G B) in the
1729 means remove a mask, if any. */
1731 mask
= image_spec_value (spec
, QCheuristic_mask
, NULL
);
1733 x_build_heuristic_mask (f
, img
, mask
);
1738 mask
= image_spec_value (spec
, QCmask
, &found_p
);
1740 if (EQ (mask
, Qheuristic
))
1741 x_build_heuristic_mask (f
, img
, Qt
);
1742 else if (CONSP (mask
)
1743 && EQ (XCAR (mask
), Qheuristic
))
1745 if (CONSP (XCDR (mask
)))
1746 x_build_heuristic_mask (f
, img
, XCAR (XCDR (mask
)));
1748 x_build_heuristic_mask (f
, img
, XCDR (mask
));
1750 else if (NILP (mask
) && found_p
&& img
->mask
)
1752 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
1753 img
->mask
= NO_PIXMAP
;
1758 /* Should we apply an image transformation algorithm? */
1759 conversion
= image_spec_value (spec
, QCconversion
, NULL
);
1760 if (EQ (conversion
, Qdisabled
))
1761 x_disable_image (f
, img
);
1762 else if (EQ (conversion
, Qlaplace
))
1764 else if (EQ (conversion
, Qemboss
))
1766 else if (CONSP (conversion
)
1767 && EQ (XCAR (conversion
), Qedge_detection
))
1770 tem
= XCDR (conversion
);
1772 x_edge_detection (f
, img
,
1773 Fplist_get (tem
, QCmatrix
),
1774 Fplist_get (tem
, QCcolor_adjustment
));
1780 /* Return the id of image with Lisp specification SPEC on frame F.
1781 SPEC must be a valid Lisp image specification (see valid_image_p). */
1784 lookup_image (f
, spec
)
1788 struct image_cache
*c
;
1791 struct gcpro gcpro1
;
1794 /* F must be a window-system frame, and SPEC must be a valid image
1796 xassert (FRAME_WINDOW_P (f
));
1797 xassert (valid_image_p (spec
));
1799 c
= FRAME_IMAGE_CACHE (f
);
1803 /* Look up SPEC in the hash table of the image cache. */
1804 hash
= sxhash (spec
, 0);
1805 img
= search_image_cache (f
, spec
, hash
);
1806 if (img
&& img
->load_failed_p
)
1808 free_image (f
, img
);
1812 /* If not found, create a new image and cache it. */
1815 extern Lisp_Object Qpostscript
;
1818 img
= make_image (spec
, hash
);
1819 cache_image (f
, img
);
1820 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
1821 img
->frame_foreground
= FRAME_FOREGROUND_PIXEL (f
);
1822 img
->frame_background
= FRAME_BACKGROUND_PIXEL (f
);
1824 /* If we can't load the image, and we don't have a width and
1825 height, use some arbitrary width and height so that we can
1826 draw a rectangle for it. */
1827 if (img
->load_failed_p
)
1831 value
= image_spec_value (spec
, QCwidth
, NULL
);
1832 img
->width
= (INTEGERP (value
)
1833 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
1834 value
= image_spec_value (spec
, QCheight
, NULL
);
1835 img
->height
= (INTEGERP (value
)
1836 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
1840 /* Handle image type independent image attributes
1841 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
1842 `:background COLOR'. */
1843 Lisp_Object ascent
, margin
, relief
, bg
;
1845 ascent
= image_spec_value (spec
, QCascent
, NULL
);
1846 if (INTEGERP (ascent
))
1847 img
->ascent
= XFASTINT (ascent
);
1848 else if (EQ (ascent
, Qcenter
))
1849 img
->ascent
= CENTERED_IMAGE_ASCENT
;
1851 margin
= image_spec_value (spec
, QCmargin
, NULL
);
1852 if (INTEGERP (margin
) && XINT (margin
) >= 0)
1853 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
1854 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
1855 && INTEGERP (XCDR (margin
)))
1857 if (XINT (XCAR (margin
)) > 0)
1858 img
->hmargin
= XFASTINT (XCAR (margin
));
1859 if (XINT (XCDR (margin
)) > 0)
1860 img
->vmargin
= XFASTINT (XCDR (margin
));
1863 relief
= image_spec_value (spec
, QCrelief
, NULL
);
1864 if (INTEGERP (relief
))
1866 img
->relief
= XINT (relief
);
1867 img
->hmargin
+= eabs (img
->relief
);
1868 img
->vmargin
+= eabs (img
->relief
);
1871 if (! img
->background_valid
)
1873 bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
1877 = x_alloc_image_color (f
, img
, bg
,
1878 FRAME_BACKGROUND_PIXEL (f
));
1879 img
->background_valid
= 1;
1883 /* Do image transformations and compute masks, unless we
1884 don't have the image yet. */
1885 if (!EQ (*img
->type
->type
, Qpostscript
))
1886 postprocess_image (f
, img
);
1892 /* We're using IMG, so set its timestamp to `now'. */
1893 EMACS_GET_TIME (now
);
1894 img
->timestamp
= EMACS_SECS (now
);
1898 /* Value is the image id. */
1903 /* Cache image IMG in the image cache of frame F. */
1906 cache_image (f
, img
)
1910 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1913 /* Find a free slot in c->images. */
1914 for (i
= 0; i
< c
->used
; ++i
)
1915 if (c
->images
[i
] == NULL
)
1918 /* If no free slot found, maybe enlarge c->images. */
1919 if (i
== c
->used
&& c
->used
== c
->size
)
1922 c
->images
= (struct image
**) xrealloc (c
->images
,
1923 c
->size
* sizeof *c
->images
);
1926 /* Add IMG to c->images, and assign IMG an id. */
1932 /* Add IMG to the cache's hash table. */
1933 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1934 img
->next
= c
->buckets
[i
];
1936 img
->next
->prev
= img
;
1938 c
->buckets
[i
] = img
;
1942 /* Call FN on every image in the image cache of frame F. Used to mark
1943 Lisp Objects in the image cache. */
1945 /* Mark Lisp objects in image IMG. */
1951 mark_object (img
->spec
);
1952 mark_object (img
->dependencies
);
1954 if (!NILP (img
->data
.lisp_val
))
1955 mark_object (img
->data
.lisp_val
);
1960 mark_image_cache (struct image_cache
*c
)
1965 for (i
= 0; i
< c
->used
; ++i
)
1967 mark_image (c
->images
[i
]);
1973 /***********************************************************************
1974 X / NS / W32 support code
1975 ***********************************************************************/
1979 /* Macro for defining functions that will be loaded from image DLLs. */
1980 #define DEF_IMGLIB_FN(func) int (FAR CDECL *fn_##func)()
1982 /* Macro for loading those image functions from the library. */
1983 #define LOAD_IMGLIB_FN(lib,func) { \
1984 fn_##func = (void *) GetProcAddress (lib, #func); \
1985 if (!fn_##func) return 0; \
1988 /* Load a DLL implementing an image type.
1989 The `image-library-alist' variable associates a symbol,
1990 identifying an image type, to a list of possible filenames.
1991 The function returns NULL if no library could be loaded for
1992 the given image type, or if the library was previously loaded;
1993 else the handle of the DLL. */
1995 w32_delayed_load (Lisp_Object libraries
, Lisp_Object type
)
1997 HMODULE library
= NULL
;
1999 if (CONSP (libraries
) && NILP (Fassq (type
, Vimage_type_cache
)))
2001 Lisp_Object dlls
= Fassq (type
, libraries
);
2004 for (dlls
= XCDR (dlls
); CONSP (dlls
); dlls
= XCDR (dlls
))
2006 CHECK_STRING_CAR (dlls
);
2007 if (library
= LoadLibrary (SDATA (XCAR (dlls
))))
2015 #endif /* HAVE_NTGUI */
2017 static int x_create_x_image_and_pixmap
P_ ((struct frame
*, int, int, int,
2018 XImagePtr
*, Pixmap
*));
2019 static void x_destroy_x_image
P_ ((XImagePtr
));
2020 static void x_put_x_image
P_ ((struct frame
*, XImagePtr
, Pixmap
, int, int));
2023 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
2024 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
2025 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
2026 via xmalloc. Print error messages via image_error if an error
2027 occurs. Value is non-zero if successful.
2029 On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
2030 should indicate the bit depth of the image. */
2033 x_create_x_image_and_pixmap (f
, width
, height
, depth
, ximg
, pixmap
)
2035 int width
, height
, depth
;
2039 #ifdef HAVE_X_WINDOWS
2040 Display
*display
= FRAME_X_DISPLAY (f
);
2041 Window window
= FRAME_X_WINDOW (f
);
2042 Screen
*screen
= FRAME_X_SCREEN (f
);
2044 xassert (interrupt_input_blocked
);
2047 depth
= DefaultDepthOfScreen (screen
);
2048 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
2049 depth
, ZPixmap
, 0, NULL
, width
, height
,
2050 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
2053 image_error ("Unable to allocate X image", Qnil
, Qnil
);
2057 /* Allocate image raster. */
2058 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
2060 /* Allocate a pixmap of the same size. */
2061 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
2062 if (*pixmap
== NO_PIXMAP
)
2064 x_destroy_x_image (*ximg
);
2066 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
2071 #endif /* HAVE_X_WINDOWS */
2075 BITMAPINFOHEADER
*header
;
2077 int scanline_width_bits
;
2079 int palette_colors
= 0;
2084 if (depth
!= 1 && depth
!= 4 && depth
!= 8
2085 && depth
!= 16 && depth
!= 24 && depth
!= 32)
2087 image_error ("Invalid image bit depth specified", Qnil
, Qnil
);
2091 scanline_width_bits
= width
* depth
;
2092 remainder
= scanline_width_bits
% 32;
2095 scanline_width_bits
+= 32 - remainder
;
2097 /* Bitmaps with a depth less than 16 need a palette. */
2098 /* BITMAPINFO structure already contains the first RGBQUAD. */
2100 palette_colors
= 1 << depth
- 1;
2102 *ximg
= xmalloc (sizeof (XImage
) + palette_colors
* sizeof (RGBQUAD
));
2105 image_error ("Unable to allocate memory for XImage", Qnil
, Qnil
);
2109 header
= &((*ximg
)->info
.bmiHeader
);
2110 bzero (&((*ximg
)->info
), sizeof (BITMAPINFO
));
2111 header
->biSize
= sizeof (*header
);
2112 header
->biWidth
= width
;
2113 header
->biHeight
= -height
; /* negative indicates a top-down bitmap. */
2114 header
->biPlanes
= 1;
2115 header
->biBitCount
= depth
;
2116 header
->biCompression
= BI_RGB
;
2117 header
->biClrUsed
= palette_colors
;
2119 /* TODO: fill in palette. */
2122 (*ximg
)->info
.bmiColors
[0].rgbBlue
= 0;
2123 (*ximg
)->info
.bmiColors
[0].rgbGreen
= 0;
2124 (*ximg
)->info
.bmiColors
[0].rgbRed
= 0;
2125 (*ximg
)->info
.bmiColors
[0].rgbReserved
= 0;
2126 (*ximg
)->info
.bmiColors
[1].rgbBlue
= 255;
2127 (*ximg
)->info
.bmiColors
[1].rgbGreen
= 255;
2128 (*ximg
)->info
.bmiColors
[1].rgbRed
= 255;
2129 (*ximg
)->info
.bmiColors
[1].rgbReserved
= 0;
2132 hdc
= get_frame_dc (f
);
2134 /* Create a DIBSection and raster array for the bitmap,
2135 and store its handle in *pixmap. */
2136 *pixmap
= CreateDIBSection (hdc
, &((*ximg
)->info
),
2137 (depth
< 16) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
,
2138 /* casting avoids a GCC warning */
2139 (void **)&((*ximg
)->data
), NULL
, 0);
2141 /* Realize display palette and garbage all frames. */
2142 release_frame_dc (f
, hdc
);
2144 if (*pixmap
== NULL
)
2146 DWORD err
= GetLastError ();
2147 Lisp_Object errcode
;
2148 /* All system errors are < 10000, so the following is safe. */
2149 XSETINT (errcode
, (int) err
);
2150 image_error ("Unable to create bitmap, error code %d", errcode
, Qnil
);
2151 x_destroy_x_image (*ximg
);
2157 #endif /* HAVE_NTGUI */
2160 *pixmap
= ns_image_for_XPM(width
, height
, depth
);
2164 image_error ("Unable to allocate NSImage for XPM pixmap", Qnil
, Qnil
);
2173 /* Destroy XImage XIMG. Free XIMG->data. */
2176 x_destroy_x_image (ximg
)
2179 xassert (interrupt_input_blocked
);
2182 #ifdef HAVE_X_WINDOWS
2185 XDestroyImage (ximg
);
2186 #endif /* HAVE_X_WINDOWS */
2188 /* Data will be freed by DestroyObject. */
2191 #endif /* HAVE_NTGUI */
2193 ns_release_object(ximg
);
2194 #endif /* HAVE_NS */
2199 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
2200 are width and height of both the image and pixmap. */
2203 x_put_x_image (f
, ximg
, pixmap
, width
, height
)
2209 #ifdef HAVE_X_WINDOWS
2212 xassert (interrupt_input_blocked
);
2213 gc
= XCreateGC (FRAME_X_DISPLAY (f
), pixmap
, 0, NULL
);
2214 XPutImage (FRAME_X_DISPLAY (f
), pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
2215 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
2216 #endif /* HAVE_X_WINDOWS */
2219 #if 0 /* I don't think this is necessary looking at where it is used. */
2220 HDC hdc
= get_frame_dc (f
);
2221 SetDIBits (hdc
, pixmap
, 0, height
, ximg
->data
, &(ximg
->info
), DIB_RGB_COLORS
);
2222 release_frame_dc (f
, hdc
);
2224 #endif /* HAVE_NTGUI */
2227 xassert (ximg
== pixmap
);
2228 ns_retain_object(ximg
);
2233 /***********************************************************************
2235 ***********************************************************************/
2237 static unsigned char *slurp_file
P_ ((char *, int *));
2240 /* Find image file FILE. Look in data-directory/images, then
2241 x-bitmap-file-path. Value is the encoded full name of the file
2242 found, or nil if not found. */
2245 x_find_image_file (file
)
2248 Lisp_Object file_found
, search_path
;
2249 struct gcpro gcpro1
, gcpro2
;
2253 /* TODO I think this should use something like image-load-path
2254 instead. Unfortunately, that can contain non-string elements. */
2255 search_path
= Fcons (Fexpand_file_name (build_string ("images"),
2257 Vx_bitmap_file_path
);
2258 GCPRO2 (file_found
, search_path
);
2260 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
2261 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
2267 file_found
= ENCODE_FILE (file_found
);
2276 /* Read FILE into memory. Value is a pointer to a buffer allocated
2277 with xmalloc holding FILE's contents. Value is null if an error
2278 occurred. *SIZE is set to the size of the file. */
2280 static unsigned char *
2281 slurp_file (file
, size
)
2286 unsigned char *buf
= NULL
;
2289 if (stat (file
, &st
) == 0
2290 && (fp
= fopen (file
, "rb")) != NULL
2291 && (buf
= (unsigned char *) xmalloc (st
.st_size
),
2292 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
2313 /***********************************************************************
2315 ***********************************************************************/
2317 static int xbm_scan
P_ ((unsigned char **, unsigned char *, char *, int *));
2318 static int xbm_load
P_ ((struct frame
*f
, struct image
*img
));
2319 static int xbm_load_image
P_ ((struct frame
*f
, struct image
*img
,
2320 unsigned char *, unsigned char *));
2321 static int xbm_image_p
P_ ((Lisp_Object object
));
2322 static int xbm_read_bitmap_data
P_ ((struct frame
*f
,
2323 unsigned char *, unsigned char *,
2324 int *, int *, unsigned char **, int));
2325 static int xbm_file_p
P_ ((Lisp_Object
));
2328 /* Indices of image specification fields in xbm_format, below. */
2330 enum xbm_keyword_index
2348 /* Vector of image_keyword structures describing the format
2349 of valid XBM image specifications. */
2351 static const struct image_keyword xbm_format
[XBM_LAST
] =
2353 {":type", IMAGE_SYMBOL_VALUE
, 1},
2354 {":file", IMAGE_STRING_VALUE
, 0},
2355 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2356 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2357 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2358 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
2359 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
2360 {":ascent", IMAGE_ASCENT_VALUE
, 0},
2361 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
2362 {":relief", IMAGE_INTEGER_VALUE
, 0},
2363 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2364 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2365 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
2368 /* Structure describing the image type XBM. */
2370 static struct image_type xbm_type
=
2379 /* Tokens returned from xbm_scan. */
2388 /* Return non-zero if OBJECT is a valid XBM-type image specification.
2389 A valid specification is a list starting with the symbol `image'
2390 The rest of the list is a property list which must contain an
2393 If the specification specifies a file to load, it must contain
2394 an entry `:file FILENAME' where FILENAME is a string.
2396 If the specification is for a bitmap loaded from memory it must
2397 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
2398 WIDTH and HEIGHT are integers > 0. DATA may be:
2400 1. a string large enough to hold the bitmap data, i.e. it must
2401 have a size >= (WIDTH + 7) / 8 * HEIGHT
2403 2. a bool-vector of size >= WIDTH * HEIGHT
2405 3. a vector of strings or bool-vectors, one for each line of the
2408 4. a string containing an in-memory XBM file. WIDTH and HEIGHT
2409 may not be specified in this case because they are defined in the
2412 Both the file and data forms may contain the additional entries
2413 `:background COLOR' and `:foreground COLOR'. If not present,
2414 foreground and background of the frame on which the image is
2415 displayed is used. */
2418 xbm_image_p (object
)
2421 struct image_keyword kw
[XBM_LAST
];
2423 bcopy (xbm_format
, kw
, sizeof kw
);
2424 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
2427 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
2429 if (kw
[XBM_FILE
].count
)
2431 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
2434 else if (kw
[XBM_DATA
].count
&& xbm_file_p (kw
[XBM_DATA
].value
))
2436 /* In-memory XBM file. */
2437 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_FILE
].count
)
2445 /* Entries for `:width', `:height' and `:data' must be present. */
2446 if (!kw
[XBM_WIDTH
].count
2447 || !kw
[XBM_HEIGHT
].count
2448 || !kw
[XBM_DATA
].count
)
2451 data
= kw
[XBM_DATA
].value
;
2452 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
2453 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
2455 /* Check type of data, and width and height against contents of
2461 /* Number of elements of the vector must be >= height. */
2462 if (XVECTOR (data
)->size
< height
)
2465 /* Each string or bool-vector in data must be large enough
2466 for one line of the image. */
2467 for (i
= 0; i
< height
; ++i
)
2469 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
2474 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
2477 else if (BOOL_VECTOR_P (elt
))
2479 if (XBOOL_VECTOR (elt
)->size
< width
)
2486 else if (STRINGP (data
))
2489 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
2492 else if (BOOL_VECTOR_P (data
))
2494 if (XBOOL_VECTOR (data
)->size
< width
* height
)
2505 /* Scan a bitmap file. FP is the stream to read from. Value is
2506 either an enumerator from enum xbm_token, or a character for a
2507 single-character token, or 0 at end of file. If scanning an
2508 identifier, store the lexeme of the identifier in SVAL. If
2509 scanning a number, store its value in *IVAL. */
2512 xbm_scan (s
, end
, sval
, ival
)
2513 unsigned char **s
, *end
;
2521 /* Skip white space. */
2522 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
2527 else if (isdigit (c
))
2529 int value
= 0, digit
;
2531 if (c
== '0' && *s
< end
)
2534 if (c
== 'x' || c
== 'X')
2541 else if (c
>= 'a' && c
<= 'f')
2542 digit
= c
- 'a' + 10;
2543 else if (c
>= 'A' && c
<= 'F')
2544 digit
= c
- 'A' + 10;
2547 value
= 16 * value
+ digit
;
2550 else if (isdigit (c
))
2554 && (c
= *(*s
)++, isdigit (c
)))
2555 value
= 8 * value
+ c
- '0';
2562 && (c
= *(*s
)++, isdigit (c
)))
2563 value
= 10 * value
+ c
- '0';
2571 else if (isalpha (c
) || c
== '_')
2575 && (c
= *(*s
)++, (isalnum (c
) || c
== '_')))
2582 else if (c
== '/' && **s
== '*')
2584 /* C-style comment. */
2586 while (**s
&& (**s
!= '*' || *(*s
+ 1) != '/'))
2600 /* Create a Windows bitmap from X bitmap data. */
2602 w32_create_pixmap_from_bitmap_data (int width
, int height
, char *data
)
2604 static unsigned char swap_nibble
[16]
2605 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
2606 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
2607 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
2608 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
2610 unsigned char *bits
, *p
;
2613 w1
= (width
+ 7) / 8; /* nb of 8bits elt in X bitmap */
2614 w2
= ((width
+ 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
2615 bits
= (unsigned char *) alloca (height
* w2
);
2616 bzero (bits
, height
* w2
);
2617 for (i
= 0; i
< height
; i
++)
2620 for (j
= 0; j
< w1
; j
++)
2622 /* Bitswap XBM bytes to match how Windows does things. */
2623 unsigned char c
= *data
++;
2624 *p
++ = (unsigned char)((swap_nibble
[c
& 0xf] << 4)
2625 | (swap_nibble
[(c
>>4) & 0xf]));
2628 bmp
= CreateBitmap (width
, height
, 1, 1, (char *) bits
);
2634 convert_mono_to_color_image (f
, img
, foreground
, background
)
2637 COLORREF foreground
, background
;
2639 HDC hdc
, old_img_dc
, new_img_dc
;
2640 HGDIOBJ old_prev
, new_prev
;
2643 hdc
= get_frame_dc (f
);
2644 old_img_dc
= CreateCompatibleDC (hdc
);
2645 new_img_dc
= CreateCompatibleDC (hdc
);
2646 new_pixmap
= CreateCompatibleBitmap (hdc
, img
->width
, img
->height
);
2647 release_frame_dc (f
, hdc
);
2648 old_prev
= SelectObject (old_img_dc
, img
->pixmap
);
2649 new_prev
= SelectObject (new_img_dc
, new_pixmap
);
2650 /* Windows convention for mono bitmaps is black = background,
2651 white = foreground. */
2652 SetTextColor (new_img_dc
, background
);
2653 SetBkColor (new_img_dc
, foreground
);
2655 BitBlt (new_img_dc
, 0, 0, img
->width
, img
->height
, old_img_dc
,
2658 SelectObject (old_img_dc
, old_prev
);
2659 SelectObject (new_img_dc
, new_prev
);
2660 DeleteDC (old_img_dc
);
2661 DeleteDC (new_img_dc
);
2662 DeleteObject (img
->pixmap
);
2663 if (new_pixmap
== 0)
2664 fprintf (stderr
, "Failed to convert image to color.\n");
2666 img
->pixmap
= new_pixmap
;
2669 #define XBM_BIT_SHUFFLE(b) (~(b))
2673 #define XBM_BIT_SHUFFLE(b) (b)
2675 #endif /* HAVE_NTGUI */
2679 Create_Pixmap_From_Bitmap_Data (f
, img
, data
, fg
, bg
, non_default_colors
)
2683 RGB_PIXEL_COLOR fg
, bg
;
2684 int non_default_colors
;
2688 = w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
, data
);
2690 /* If colors were specified, transfer the bitmap to a color one. */
2691 if (non_default_colors
)
2692 convert_mono_to_color_image (f
, img
, fg
, bg
);
2694 #elif defined (HAVE_NS)
2695 img
->pixmap
= ns_image_from_XBM(data
, img
->width
, img
->height
);
2699 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
2702 img
->width
, img
->height
,
2704 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
2705 #endif /* !HAVE_NTGUI && !HAVE_NS */
2710 /* Replacement for XReadBitmapFileData which isn't available under old
2711 X versions. CONTENTS is a pointer to a buffer to parse; END is the
2712 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
2713 the image. Return in *DATA the bitmap data allocated with xmalloc.
2714 Value is non-zero if successful. DATA null means just test if
2715 CONTENTS looks like an in-memory XBM file. If INHIBIT_IMAGE_ERROR
2716 is non-zero, inhibit the call to image_error when the image size is
2717 invalid (the bitmap remains unread). */
2720 xbm_read_bitmap_data (f
, contents
, end
, width
, height
, data
, inhibit_image_error
)
2722 unsigned char *contents
, *end
;
2723 int *width
, *height
;
2724 unsigned char **data
;
2725 int inhibit_image_error
;
2727 unsigned char *s
= contents
;
2728 char buffer
[BUFSIZ
];
2731 int bytes_per_line
, i
, nbytes
;
2737 LA1 = xbm_scan (&s, end, buffer, &value)
2739 #define expect(TOKEN) \
2740 if (LA1 != (TOKEN)) \
2745 #define expect_ident(IDENT) \
2746 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
2751 *width
= *height
= -1;
2754 LA1
= xbm_scan (&s
, end
, buffer
, &value
);
2756 /* Parse defines for width, height and hot-spots. */
2760 expect_ident ("define");
2761 expect (XBM_TK_IDENT
);
2763 if (LA1
== XBM_TK_NUMBER
)
2765 char *p
= strrchr (buffer
, '_');
2766 p
= p
? p
+ 1 : buffer
;
2767 if (strcmp (p
, "width") == 0)
2769 else if (strcmp (p
, "height") == 0)
2772 expect (XBM_TK_NUMBER
);
2775 if (!check_image_size (f
, *width
, *height
))
2777 if (!inhibit_image_error
)
2778 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
2781 else if (data
== NULL
)
2784 /* Parse bits. Must start with `static'. */
2785 expect_ident ("static");
2786 if (LA1
== XBM_TK_IDENT
)
2788 if (strcmp (buffer
, "unsigned") == 0)
2791 expect_ident ("char");
2793 else if (strcmp (buffer
, "short") == 0)
2797 if (*width
% 16 && *width
% 16 < 9)
2800 else if (strcmp (buffer
, "char") == 0)
2808 expect (XBM_TK_IDENT
);
2814 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
2815 nbytes
= bytes_per_line
* *height
;
2816 p
= *data
= (unsigned char *) xmalloc (nbytes
);
2820 for (i
= 0; i
< nbytes
; i
+= 2)
2823 expect (XBM_TK_NUMBER
);
2825 *p
++ = XBM_BIT_SHUFFLE (val
);
2826 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
2827 *p
++ = XBM_BIT_SHUFFLE (value
>> 8);
2829 if (LA1
== ',' || LA1
== '}')
2837 for (i
= 0; i
< nbytes
; ++i
)
2840 expect (XBM_TK_NUMBER
);
2842 *p
++ = XBM_BIT_SHUFFLE (val
);
2844 if (LA1
== ',' || LA1
== '}')
2869 /* Load XBM image IMG which will be displayed on frame F from buffer
2870 CONTENTS. END is the end of the buffer. Value is non-zero if
2874 xbm_load_image (f
, img
, contents
, end
)
2877 unsigned char *contents
, *end
;
2880 unsigned char *data
;
2883 rc
= xbm_read_bitmap_data (f
, contents
, end
, &img
->width
, &img
->height
,
2887 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2888 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2889 int non_default_colors
= 0;
2892 xassert (img
->width
> 0 && img
->height
> 0);
2894 /* Get foreground and background colors, maybe allocate colors. */
2895 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
2898 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
2899 non_default_colors
= 1;
2901 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
2904 background
= x_alloc_image_color (f
, img
, value
, background
);
2905 img
->background
= background
;
2906 img
->background_valid
= 1;
2907 non_default_colors
= 1;
2910 Create_Pixmap_From_Bitmap_Data (f
, img
, data
,
2911 foreground
, background
,
2912 non_default_colors
);
2915 if (img
->pixmap
== NO_PIXMAP
)
2917 x_clear_image (f
, img
);
2918 image_error ("Unable to create X pixmap for `%s'", img
->spec
, Qnil
);
2924 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
2930 /* Value is non-zero if DATA looks like an in-memory XBM file. */
2937 return (STRINGP (data
)
2938 && xbm_read_bitmap_data (NULL
, SDATA (data
),
2939 (SDATA (data
) + SBYTES (data
)),
2944 /* Fill image IMG which is used on frame F with pixmap data. Value is
2945 non-zero if successful. */
2953 Lisp_Object file_name
;
2955 xassert (xbm_image_p (img
->spec
));
2957 /* If IMG->spec specifies a file name, create a non-file spec from it. */
2958 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
2959 if (STRINGP (file_name
))
2962 unsigned char *contents
;
2964 struct gcpro gcpro1
;
2966 file
= x_find_image_file (file_name
);
2968 if (!STRINGP (file
))
2970 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
2975 contents
= slurp_file (SDATA (file
), &size
);
2976 if (contents
== NULL
)
2978 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
2983 success_p
= xbm_load_image (f
, img
, contents
, contents
+ size
);
2988 struct image_keyword fmt
[XBM_LAST
];
2990 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2991 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2992 int non_default_colors
= 0;
2995 int in_memory_file_p
= 0;
2997 /* See if data looks like an in-memory XBM file. */
2998 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
2999 in_memory_file_p
= xbm_file_p (data
);
3001 /* Parse the image specification. */
3002 bcopy (xbm_format
, fmt
, sizeof fmt
);
3003 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
3006 /* Get specified width, and height. */
3007 if (!in_memory_file_p
)
3009 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
3010 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
3011 xassert (img
->width
> 0 && img
->height
> 0);
3014 /* Get foreground and background colors, maybe allocate colors. */
3015 if (fmt
[XBM_FOREGROUND
].count
3016 && STRINGP (fmt
[XBM_FOREGROUND
].value
))
3018 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
3020 non_default_colors
= 1;
3023 if (fmt
[XBM_BACKGROUND
].count
3024 && STRINGP (fmt
[XBM_BACKGROUND
].value
))
3026 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
3028 non_default_colors
= 1;
3031 if (in_memory_file_p
)
3032 success_p
= xbm_load_image (f
, img
, SDATA (data
),
3041 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
3043 p
= bits
= (char *) alloca (nbytes
* img
->height
);
3044 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
3046 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
3048 bcopy (SDATA (line
), p
, nbytes
);
3050 bcopy (XBOOL_VECTOR (line
)->data
, p
, nbytes
);
3053 else if (STRINGP (data
))
3054 bits
= SDATA (data
);
3056 bits
= XBOOL_VECTOR (data
)->data
;
3062 /* Windows mono bitmaps are reversed compared with X. */
3063 invertedBits
= bits
;
3064 nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
3066 bits
= (char *) alloca(nbytes
);
3067 for (i
= 0; i
< nbytes
; i
++)
3068 bits
[i
] = XBM_BIT_SHUFFLE (invertedBits
[i
]);
3071 /* Create the pixmap. */
3073 Create_Pixmap_From_Bitmap_Data (f
, img
, bits
,
3074 foreground
, background
,
3075 non_default_colors
);
3080 image_error ("Unable to create pixmap for XBM image `%s'",
3082 x_clear_image (f
, img
);
3092 /***********************************************************************
3094 ***********************************************************************/
3096 #if defined (HAVE_XPM) || defined (HAVE_NS)
3098 static int xpm_image_p
P_ ((Lisp_Object object
));
3099 static int xpm_load
P_ ((struct frame
*f
, struct image
*img
));
3100 static int xpm_valid_color_symbols_p
P_ ((Lisp_Object
));
3102 #endif /* HAVE_XPM || HAVE_NS */
3106 /* Indicate to xpm.h that we don't have Xlib. */
3108 /* simx.h in xpm defines XColor and XImage differently than Emacs. */
3109 /* It also defines Display the same way as Emacs, but gcc 3.3 still barfs. */
3110 #define XColor xpm_XColor
3111 #define XImage xpm_XImage
3112 #define Display xpm_Display
3113 #define PIXEL_ALREADY_TYPEDEFED
3114 #include "X11/xpm.h"
3119 #undef PIXEL_ALREADY_TYPEDEFED
3121 #include "X11/xpm.h"
3122 #endif /* HAVE_NTGUI */
3123 #endif /* HAVE_XPM */
3125 #if defined (HAVE_XPM) || defined (HAVE_NS)
3126 /* The symbol `xpm' identifying XPM-format images. */
3130 /* Indices of image specification fields in xpm_format, below. */
3132 enum xpm_keyword_index
3148 /* Vector of image_keyword structures describing the format
3149 of valid XPM image specifications. */
3151 static const struct image_keyword xpm_format
[XPM_LAST
] =
3153 {":type", IMAGE_SYMBOL_VALUE
, 1},
3154 {":file", IMAGE_STRING_VALUE
, 0},
3155 {":data", IMAGE_STRING_VALUE
, 0},
3156 {":ascent", IMAGE_ASCENT_VALUE
, 0},
3157 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
3158 {":relief", IMAGE_INTEGER_VALUE
, 0},
3159 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3160 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3161 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3162 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3163 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
3166 /* Structure describing the image type XPM. */
3168 static struct image_type xpm_type
=
3177 #ifdef HAVE_X_WINDOWS
3179 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
3180 functions for allocating image colors. Our own functions handle
3181 color allocation failures more gracefully than the ones on the XPM
3184 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
3185 #define ALLOC_XPM_COLORS
3187 #endif /* HAVE_X_WINDOWS */
3189 #ifdef ALLOC_XPM_COLORS
3191 static void xpm_init_color_cache
P_ ((struct frame
*, XpmAttributes
*));
3192 static void xpm_free_color_cache
P_ ((void));
3193 static int xpm_lookup_color
P_ ((struct frame
*, char *, XColor
*));
3194 static int xpm_color_bucket
P_ ((char *));
3195 static struct xpm_cached_color
*xpm_cache_color
P_ ((struct frame
*, char *,
3198 /* An entry in a hash table used to cache color definitions of named
3199 colors. This cache is necessary to speed up XPM image loading in
3200 case we do color allocations ourselves. Without it, we would need
3201 a call to XParseColor per pixel in the image. */
3203 struct xpm_cached_color
3205 /* Next in collision chain. */
3206 struct xpm_cached_color
*next
;
3208 /* Color definition (RGB and pixel color). */
3215 /* The hash table used for the color cache, and its bucket vector
3218 #define XPM_COLOR_CACHE_BUCKETS 1001
3219 struct xpm_cached_color
**xpm_color_cache
;
3221 /* Initialize the color cache. */
3224 xpm_init_color_cache (f
, attrs
)
3226 XpmAttributes
*attrs
;
3228 size_t nbytes
= XPM_COLOR_CACHE_BUCKETS
* sizeof *xpm_color_cache
;
3229 xpm_color_cache
= (struct xpm_cached_color
**) xmalloc (nbytes
);
3230 memset (xpm_color_cache
, 0, nbytes
);
3231 init_color_table ();
3233 if (attrs
->valuemask
& XpmColorSymbols
)
3238 for (i
= 0; i
< attrs
->numsymbols
; ++i
)
3239 if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
3240 attrs
->colorsymbols
[i
].value
, &color
))
3242 color
.pixel
= lookup_rgb_color (f
, color
.red
, color
.green
,
3244 xpm_cache_color (f
, attrs
->colorsymbols
[i
].name
, &color
, -1);
3249 /* Free the color cache. */
3252 xpm_free_color_cache ()
3254 struct xpm_cached_color
*p
, *next
;
3257 for (i
= 0; i
< XPM_COLOR_CACHE_BUCKETS
; ++i
)
3258 for (p
= xpm_color_cache
[i
]; p
; p
= next
)
3264 xfree (xpm_color_cache
);
3265 xpm_color_cache
= NULL
;
3266 free_color_table ();
3269 /* Return the bucket index for color named COLOR_NAME in the color
3273 xpm_color_bucket (color_name
)
3279 for (s
= color_name
; *s
; ++s
)
3281 return h
%= XPM_COLOR_CACHE_BUCKETS
;
3285 /* On frame F, cache values COLOR for color with name COLOR_NAME.
3286 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
3289 static struct xpm_cached_color
*
3290 xpm_cache_color (f
, color_name
, color
, bucket
)
3297 struct xpm_cached_color
*p
;
3300 bucket
= xpm_color_bucket (color_name
);
3302 nbytes
= sizeof *p
+ strlen (color_name
);
3303 p
= (struct xpm_cached_color
*) xmalloc (nbytes
);
3304 strcpy (p
->name
, color_name
);
3306 p
->next
= xpm_color_cache
[bucket
];
3307 xpm_color_cache
[bucket
] = p
;
3311 /* Look up color COLOR_NAME for frame F in the color cache. If found,
3312 return the cached definition in *COLOR. Otherwise, make a new
3313 entry in the cache and allocate the color. Value is zero if color
3314 allocation failed. */
3317 xpm_lookup_color (f
, color_name
, color
)
3322 struct xpm_cached_color
*p
;
3323 int h
= xpm_color_bucket (color_name
);
3325 for (p
= xpm_color_cache
[h
]; p
; p
= p
->next
)
3326 if (strcmp (p
->name
, color_name
) == 0)
3331 else if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
3334 color
->pixel
= lookup_rgb_color (f
, color
->red
, color
->green
,
3336 p
= xpm_cache_color (f
, color_name
, color
, h
);
3338 /* You get `opaque' at least from ImageMagick converting pbm to xpm
3339 with transparency, and it's useful. */
3340 else if (strcmp ("opaque", color_name
) == 0)
3342 bzero (color
, sizeof (XColor
)); /* Is this necessary/correct? */
3343 color
->pixel
= FRAME_FOREGROUND_PIXEL (f
);
3344 p
= xpm_cache_color (f
, color_name
, color
, h
);
3351 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
3352 CLOSURE is a pointer to the frame on which we allocate the
3353 color. Return in *COLOR the allocated color. Value is non-zero
3357 xpm_alloc_color (dpy
, cmap
, color_name
, color
, closure
)
3364 return xpm_lookup_color ((struct frame
*) closure
, color_name
, color
);
3368 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
3369 is a pointer to the frame on which we allocate the color. Value is
3370 non-zero if successful. */
3373 xpm_free_colors (dpy
, cmap
, pixels
, npixels
, closure
)
3383 #endif /* ALLOC_XPM_COLORS */
3388 /* XPM library details. */
3390 DEF_IMGLIB_FN (XpmFreeAttributes
);
3391 DEF_IMGLIB_FN (XpmCreateImageFromBuffer
);
3392 DEF_IMGLIB_FN (XpmReadFileToImage
);
3393 DEF_IMGLIB_FN (XImageFree
);
3396 init_xpm_functions (Lisp_Object libraries
)
3400 if (!(library
= w32_delayed_load (libraries
, Qxpm
)))
3403 LOAD_IMGLIB_FN (library
, XpmFreeAttributes
);
3404 LOAD_IMGLIB_FN (library
, XpmCreateImageFromBuffer
);
3405 LOAD_IMGLIB_FN (library
, XpmReadFileToImage
);
3406 LOAD_IMGLIB_FN (library
, XImageFree
);
3410 #endif /* HAVE_NTGUI */
3413 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
3414 for XPM images. Such a list must consist of conses whose car and
3418 xpm_valid_color_symbols_p (color_symbols
)
3419 Lisp_Object color_symbols
;
3421 while (CONSP (color_symbols
))
3423 Lisp_Object sym
= XCAR (color_symbols
);
3425 || !STRINGP (XCAR (sym
))
3426 || !STRINGP (XCDR (sym
)))
3428 color_symbols
= XCDR (color_symbols
);
3431 return NILP (color_symbols
);
3435 /* Value is non-zero if OBJECT is a valid XPM image specification. */
3438 xpm_image_p (object
)
3441 struct image_keyword fmt
[XPM_LAST
];
3442 bcopy (xpm_format
, fmt
, sizeof fmt
);
3443 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
3444 /* Either `:file' or `:data' must be present. */
3445 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
3446 /* Either no `:color-symbols' or it's a list of conses
3447 whose car and cdr are strings. */
3448 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
3449 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
)));
3452 #endif /* HAVE_XPM || HAVE_NS */
3454 #if defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
3456 x_create_bitmap_from_xpm_data (f
, bits
)
3460 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3462 XpmAttributes attrs
;
3463 Pixmap bitmap
, mask
;
3465 bzero (&attrs
, sizeof attrs
);
3467 attrs
.visual
= FRAME_X_VISUAL (f
);
3468 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3469 attrs
.valuemask
|= XpmVisual
;
3470 attrs
.valuemask
|= XpmColormap
;
3472 rc
= XpmCreatePixmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3473 bits
, &bitmap
, &mask
, &attrs
);
3474 if (rc
!= XpmSuccess
)
3476 XpmFreeAttributes (&attrs
);
3480 id
= x_allocate_bitmap_record (f
);
3481 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
3482 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
3483 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
3484 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
3485 dpyinfo
->bitmaps
[id
- 1].height
= attrs
.height
;
3486 dpyinfo
->bitmaps
[id
- 1].width
= attrs
.width
;
3487 dpyinfo
->bitmaps
[id
- 1].depth
= attrs
.depth
;
3488 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
3490 XpmFreeAttributes (&attrs
);
3493 #endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */
3495 /* Load image IMG which will be displayed on frame F. Value is
3496 non-zero if successful. */
3506 XpmAttributes attrs
;
3507 Lisp_Object specified_file
, color_symbols
;
3510 xpm_XImage
* xpm_image
= NULL
, * xpm_mask
= NULL
;
3511 #endif /* HAVE_NTGUI */
3513 /* Configure the XPM lib. Use the visual of frame F. Allocate
3514 close colors. Return colors allocated. */
3515 bzero (&attrs
, sizeof attrs
);
3518 attrs
.visual
= FRAME_X_VISUAL (f
);
3519 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3520 attrs
.valuemask
|= XpmVisual
;
3521 attrs
.valuemask
|= XpmColormap
;
3522 #endif /* HAVE_NTGUI */
3524 #ifdef ALLOC_XPM_COLORS
3525 /* Allocate colors with our own functions which handle
3526 failing color allocation more gracefully. */
3527 attrs
.color_closure
= f
;
3528 attrs
.alloc_color
= xpm_alloc_color
;
3529 attrs
.free_colors
= xpm_free_colors
;
3530 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
3531 #else /* not ALLOC_XPM_COLORS */
3532 /* Let the XPM lib allocate colors. */
3533 attrs
.valuemask
|= XpmReturnAllocPixels
;
3534 #ifdef XpmAllocCloseColors
3535 attrs
.alloc_close_colors
= 1;
3536 attrs
.valuemask
|= XpmAllocCloseColors
;
3537 #else /* not XpmAllocCloseColors */
3538 attrs
.closeness
= 600;
3539 attrs
.valuemask
|= XpmCloseness
;
3540 #endif /* not XpmAllocCloseColors */
3541 #endif /* ALLOC_XPM_COLORS */
3543 /* If image specification contains symbolic color definitions, add
3544 these to `attrs'. */
3545 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
3546 if (CONSP (color_symbols
))
3549 XpmColorSymbol
*xpm_syms
;
3552 attrs
.valuemask
|= XpmColorSymbols
;
3554 /* Count number of symbols. */
3555 attrs
.numsymbols
= 0;
3556 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
3559 /* Allocate an XpmColorSymbol array. */
3560 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
3561 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
3562 bzero (xpm_syms
, size
);
3563 attrs
.colorsymbols
= xpm_syms
;
3565 /* Fill the color symbol array. */
3566 for (tail
= color_symbols
, i
= 0;
3568 ++i
, tail
= XCDR (tail
))
3570 Lisp_Object name
= XCAR (XCAR (tail
));
3571 Lisp_Object color
= XCDR (XCAR (tail
));
3572 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
3573 strcpy (xpm_syms
[i
].name
, SDATA (name
));
3574 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
3575 strcpy (xpm_syms
[i
].value
, SDATA (color
));
3579 /* Create a pixmap for the image, either from a file, or from a
3580 string buffer containing data in the same format as an XPM file. */
3581 #ifdef ALLOC_XPM_COLORS
3582 xpm_init_color_cache (f
, &attrs
);
3585 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
3589 HDC frame_dc
= get_frame_dc (f
);
3590 hdc
= CreateCompatibleDC (frame_dc
);
3591 release_frame_dc (f
, frame_dc
);
3593 #endif /* HAVE_NTGUI */
3595 if (STRINGP (specified_file
))
3597 Lisp_Object file
= x_find_image_file (specified_file
);
3598 if (!STRINGP (file
))
3600 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
3605 /* XpmReadFileToPixmap is not available in the Windows port of
3606 libxpm. But XpmReadFileToImage almost does what we want. */
3607 rc
= fn_XpmReadFileToImage (&hdc
, SDATA (file
),
3608 &xpm_image
, &xpm_mask
,
3611 rc
= XpmReadFileToPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3612 SDATA (file
), &img
->pixmap
, &img
->mask
,
3614 #endif /* HAVE_NTGUI */
3618 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
3620 /* XpmCreatePixmapFromBuffer is not available in the Windows port
3621 of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
3622 rc
= fn_XpmCreateImageFromBuffer (&hdc
, SDATA (buffer
),
3623 &xpm_image
, &xpm_mask
,
3626 rc
= XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3628 &img
->pixmap
, &img
->mask
,
3630 #endif /* HAVE_NTGUI */
3633 if (rc
== XpmSuccess
)
3635 #if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS)
3636 img
->colors
= colors_in_color_table (&img
->ncolors
);
3637 #else /* not ALLOC_XPM_COLORS */
3641 /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
3642 plus some duplicate attributes. */
3643 if (xpm_image
&& xpm_image
->bitmap
)
3645 img
->pixmap
= xpm_image
->bitmap
;
3646 /* XImageFree in libXpm frees XImage struct without destroying
3647 the bitmap, which is what we want. */
3648 fn_XImageFree (xpm_image
);
3650 if (xpm_mask
&& xpm_mask
->bitmap
)
3652 /* The mask appears to be inverted compared with what we expect.
3653 TODO: invert our expectations. See other places where we
3654 have to invert bits because our idea of masks is backwards. */
3656 old_obj
= SelectObject (hdc
, xpm_mask
->bitmap
);
3658 PatBlt (hdc
, 0, 0, xpm_mask
->width
, xpm_mask
->height
, DSTINVERT
);
3659 SelectObject (hdc
, old_obj
);
3661 img
->mask
= xpm_mask
->bitmap
;
3662 fn_XImageFree (xpm_mask
);
3667 #endif /* HAVE_NTGUI */
3669 /* Remember allocated colors. */
3670 img
->ncolors
= attrs
.nalloc_pixels
;
3671 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
3672 * sizeof *img
->colors
);
3673 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
3675 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
3676 #ifdef DEBUG_X_COLORS
3677 register_color (img
->colors
[i
]);
3680 #endif /* not ALLOC_XPM_COLORS */
3682 img
->width
= attrs
.width
;
3683 img
->height
= attrs
.height
;
3684 xassert (img
->width
> 0 && img
->height
> 0);
3686 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
3688 fn_XpmFreeAttributes (&attrs
);
3690 XpmFreeAttributes (&attrs
);
3691 #endif /* HAVE_NTGUI */
3697 #endif /* HAVE_NTGUI */
3702 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
3705 case XpmFileInvalid
:
3706 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
3710 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
3713 case XpmColorFailed
:
3714 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
3718 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
3723 #ifdef ALLOC_XPM_COLORS
3724 xpm_free_color_cache ();
3726 return rc
== XpmSuccess
;
3729 #endif /* HAVE_XPM */
3731 #if defined (HAVE_NS) && !defined (HAVE_XPM)
3733 /* XPM support functions for NS where libxpm is not available.
3734 Only XPM version 3 (without any extensions) is supported. */
3736 static int xpm_scan
P_ ((const unsigned char **, const unsigned char *,
3737 const unsigned char **, int *));
3738 static Lisp_Object xpm_make_color_table_v
3739 P_ ((void (**) (Lisp_Object
, const unsigned char *, int, Lisp_Object
),
3740 Lisp_Object (**) (Lisp_Object
, const unsigned char *, int)));
3741 static void xpm_put_color_table_v
P_ ((Lisp_Object
, const unsigned char *,
3743 static Lisp_Object xpm_get_color_table_v
P_ ((Lisp_Object
,
3744 const unsigned char *, int));
3745 static Lisp_Object xpm_make_color_table_h
3746 P_ ((void (**) (Lisp_Object
, const unsigned char *, int, Lisp_Object
),
3747 Lisp_Object (**) (Lisp_Object
, const unsigned char *, int)));
3748 static void xpm_put_color_table_h
P_ ((Lisp_Object
, const unsigned char *,
3750 static Lisp_Object xpm_get_color_table_h
P_ ((Lisp_Object
,
3751 const unsigned char *, int));
3752 static int xpm_str_to_color_key
P_ ((const char *));
3753 static int xpm_load_image
P_ ((struct frame
*, struct image
*,
3754 const unsigned char *, const unsigned char *));
3756 /* Tokens returned from xpm_scan. */
3765 /* Scan an XPM data and return a character (< 256) or a token defined
3766 by enum xpm_token above. *S and END are the start (inclusive) and
3767 the end (exclusive) addresses of the data, respectively. Advance
3768 *S while scanning. If token is either XPM_TK_IDENT or
3769 XPM_TK_STRING, *BEG and *LEN are set to the start address and the
3770 length of the corresponding token, respectively. */
3773 xpm_scan (s
, end
, beg
, len
)
3774 const unsigned char **s
, *end
, **beg
;
3781 /* Skip white-space. */
3782 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
3785 /* gnus-pointer.xpm uses '-' in its identifier.
3786 sb-dir-plus.xpm uses '+' in its identifier. */
3787 if (isalpha (c
) || c
== '_' || c
== '-' || c
== '+')
3791 && (c
= **s
, isalnum (c
) || c
== '_' || c
== '-' || c
== '+'))
3794 return XPM_TK_IDENT
;
3799 while (*s
< end
&& **s
!= '"')
3804 return XPM_TK_STRING
;
3808 if (*s
< end
&& **s
== '*')
3810 /* C-style comment. */
3814 while (*s
< end
&& *(*s
)++ != '*')
3817 while (*s
< end
&& **s
!= '/');
3831 /* Functions for color table lookup in XPM data. A key is a string
3832 specifying the color of each pixel in XPM data. A value is either
3833 an integer that specifies a pixel color, Qt that specifies
3834 transparency, or Qnil for the unspecified color. If the length of
3835 the key string is one, a vector is used as a table. Otherwise, a
3836 hash table is used. */
3839 xpm_make_color_table_v (put_func
, get_func
)
3840 void (**put_func
) (Lisp_Object
, const unsigned char *, int, Lisp_Object
);
3841 Lisp_Object (**get_func
) (Lisp_Object
, const unsigned char *, int);
3843 *put_func
= xpm_put_color_table_v
;
3844 *get_func
= xpm_get_color_table_v
;
3845 return Fmake_vector (make_number (256), Qnil
);
3849 xpm_put_color_table_v (color_table
, chars_start
, chars_len
, color
)
3850 Lisp_Object color_table
;
3851 const unsigned char *chars_start
;
3855 XVECTOR (color_table
)->contents
[*chars_start
] = color
;
3859 xpm_get_color_table_v (color_table
, chars_start
, chars_len
)
3860 Lisp_Object color_table
;
3861 const unsigned char *chars_start
;
3864 return XVECTOR (color_table
)->contents
[*chars_start
];
3868 xpm_make_color_table_h (put_func
, get_func
)
3869 void (**put_func
) (Lisp_Object
, const unsigned char *, int, Lisp_Object
);
3870 Lisp_Object (**get_func
) (Lisp_Object
, const unsigned char *, int);
3872 *put_func
= xpm_put_color_table_h
;
3873 *get_func
= xpm_get_color_table_h
;
3874 return make_hash_table (Qequal
, make_number (DEFAULT_HASH_SIZE
),
3875 make_float (DEFAULT_REHASH_SIZE
),
3876 make_float (DEFAULT_REHASH_THRESHOLD
),
3881 xpm_put_color_table_h (color_table
, chars_start
, chars_len
, color
)
3882 Lisp_Object color_table
;
3883 const unsigned char *chars_start
;
3887 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
3889 Lisp_Object chars
= make_unibyte_string (chars_start
, chars_len
);
3891 hash_lookup (table
, chars
, &hash_code
);
3892 hash_put (table
, chars
, color
, hash_code
);
3896 xpm_get_color_table_h (color_table
, chars_start
, chars_len
)
3897 Lisp_Object color_table
;
3898 const unsigned char *chars_start
;
3901 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
3902 int i
= hash_lookup (table
, make_unibyte_string (chars_start
, chars_len
),
3905 return i
>= 0 ? HASH_VALUE (table
, i
) : Qnil
;
3908 enum xpm_color_key
{
3916 static const char xpm_color_key_strings
[][4] = {"s", "m", "g4", "g", "c"};
3919 xpm_str_to_color_key (s
)
3925 i
< sizeof xpm_color_key_strings
/ sizeof xpm_color_key_strings
[0];
3927 if (strcmp (xpm_color_key_strings
[i
], s
) == 0)
3933 xpm_load_image (f
, img
, contents
, end
)
3936 const unsigned char *contents
, *end
;
3938 const unsigned char *s
= contents
, *beg
, *str
;
3939 unsigned char buffer
[BUFSIZ
];
3940 int width
, height
, x
, y
;
3941 int num_colors
, chars_per_pixel
;
3943 void (*put_color_table
) (Lisp_Object
, const unsigned char *, int, Lisp_Object
);
3944 Lisp_Object (*get_color_table
) (Lisp_Object
, const unsigned char *, int);
3945 Lisp_Object frame
, color_symbols
, color_table
;
3946 int best_key
, have_mask
= 0;
3947 XImagePtr ximg
= NULL
, mask_img
= NULL
;
3950 LA1 = xpm_scan (&s, end, &beg, &len)
3952 #define expect(TOKEN) \
3953 if (LA1 != (TOKEN)) \
3958 #define expect_ident(IDENT) \
3959 if (LA1 == XPM_TK_IDENT \
3960 && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
3965 if (!(end
- s
>= 9 && memcmp (s
, "/* XPM */", 9) == 0))
3969 expect_ident ("static");
3970 expect_ident ("char");
3972 expect (XPM_TK_IDENT
);
3977 expect (XPM_TK_STRING
);
3980 memcpy (buffer
, beg
, len
);
3982 if (sscanf (buffer
, "%d %d %d %d", &width
, &height
,
3983 &num_colors
, &chars_per_pixel
) != 4
3984 || width
<= 0 || height
<= 0
3985 || num_colors
<= 0 || chars_per_pixel
<= 0)
3988 if (!check_image_size (f
, width
, height
))
3990 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
3996 XSETFRAME (frame
, f
);
3997 if (!NILP (Fxw_display_color_p (frame
)))
3998 best_key
= XPM_COLOR_KEY_C
;
3999 else if (!NILP (Fx_display_grayscale_p (frame
)))
4000 best_key
= (XFASTINT (Fx_display_planes (frame
)) > 2
4001 ? XPM_COLOR_KEY_G
: XPM_COLOR_KEY_G4
);
4003 best_key
= XPM_COLOR_KEY_M
;
4005 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
4006 if (chars_per_pixel
== 1)
4007 color_table
= xpm_make_color_table_v (&put_color_table
,
4010 color_table
= xpm_make_color_table_h (&put_color_table
,
4013 while (num_colors
-- > 0)
4015 unsigned char *color
, *max_color
;
4016 int key
, next_key
, max_key
= 0;
4017 Lisp_Object symbol_color
= Qnil
, color_val
;
4020 expect (XPM_TK_STRING
);
4021 if (len
<= chars_per_pixel
|| len
>= BUFSIZ
+ chars_per_pixel
)
4023 memcpy (buffer
, beg
+ chars_per_pixel
, len
- chars_per_pixel
);
4024 buffer
[len
- chars_per_pixel
] = '\0';
4026 str
= strtok (buffer
, " \t");
4029 key
= xpm_str_to_color_key (str
);
4034 color
= strtok (NULL
, " \t");
4038 while ((str
= strtok (NULL
, " \t")) != NULL
)
4040 next_key
= xpm_str_to_color_key (str
);
4043 color
[strlen (color
)] = ' ';
4046 if (key
== XPM_COLOR_KEY_S
)
4048 if (NILP (symbol_color
))
4049 symbol_color
= build_string (color
);
4051 else if (max_key
< key
&& key
<= best_key
)
4061 if (!NILP (color_symbols
) && !NILP (symbol_color
))
4063 Lisp_Object specified_color
= Fassoc (symbol_color
, color_symbols
);
4065 if (CONSP (specified_color
) && STRINGP (XCDR (specified_color
)))
4067 if (xstrcasecmp (SDATA (XCDR (specified_color
)), "None") == 0)
4069 else if (x_defined_color (f
, SDATA (XCDR (specified_color
)),
4071 color_val
= make_number (cdef
.pixel
);
4074 if (NILP (color_val
) && max_key
> 0)
4076 if (xstrcasecmp (max_color
, "None") == 0)
4078 else if (x_defined_color (f
, max_color
, &cdef
, 0))
4079 color_val
= make_number (cdef
.pixel
);
4081 if (!NILP (color_val
))
4082 (*put_color_table
) (color_table
, beg
, chars_per_pixel
, color_val
);
4087 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
4088 &ximg
, &img
->pixmap
)
4090 || !x_create_x_image_and_pixmap (f
, width
, height
, 1,
4091 &mask_img
, &img
->mask
)
4095 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
4099 for (y
= 0; y
< height
; y
++)
4101 expect (XPM_TK_STRING
);
4103 if (len
< width
* chars_per_pixel
)
4105 for (x
= 0; x
< width
; x
++, str
+= chars_per_pixel
)
4107 Lisp_Object color_val
=
4108 (*get_color_table
) (color_table
, str
, chars_per_pixel
);
4110 XPutPixel (ximg
, x
, y
,
4111 (INTEGERP (color_val
) ? XINT (color_val
)
4112 : FRAME_FOREGROUND_PIXEL (f
)));
4114 XPutPixel (mask_img
, x
, y
,
4115 (!EQ (color_val
, Qt
) ? PIX_MASK_DRAW
4116 : (have_mask
= 1, PIX_MASK_RETAIN
)));
4118 if (EQ(color_val
, Qt
))
4119 ns_set_alpha(ximg
, x
, y
, 0);
4127 img
->height
= height
;
4129 /* Maybe fill in the background field while we have ximg handy. */
4130 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
4131 IMAGE_BACKGROUND (img
, f
, ximg
);
4133 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
4134 x_destroy_x_image (ximg
);
4138 /* Fill in the background_transparent field while we have the
4140 image_background_transparent (img
, f
, mask_img
);
4142 x_put_x_image (f
, mask_img
, img
->mask
, width
, height
);
4143 x_destroy_x_image (mask_img
);
4147 x_destroy_x_image (mask_img
);
4148 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4149 img
->mask
= NO_PIXMAP
;
4155 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
4157 x_destroy_x_image (ximg
);
4158 x_destroy_x_image (mask_img
);
4159 x_clear_image (f
, img
);
4173 Lisp_Object file_name
;
4175 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4176 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
4177 if (STRINGP (file_name
))
4180 unsigned char *contents
;
4182 struct gcpro gcpro1
;
4184 file
= x_find_image_file (file_name
);
4186 if (!STRINGP (file
))
4188 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
4193 contents
= slurp_file (SDATA (file
), &size
);
4194 if (contents
== NULL
)
4196 image_error ("Error loading XPM image `%s'", img
->spec
, Qnil
);
4201 success_p
= xpm_load_image (f
, img
, contents
, contents
+ size
);
4209 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
4210 success_p
= xpm_load_image (f
, img
, SDATA (data
),
4211 SDATA (data
) + SBYTES (data
));
4217 #endif /* HAVE_NS && !HAVE_XPM */
4221 /***********************************************************************
4223 ***********************************************************************/
4225 #ifdef COLOR_TABLE_SUPPORT
4227 /* An entry in the color table mapping an RGB color to a pixel color. */
4232 unsigned long pixel
;
4234 /* Next in color table collision list. */
4235 struct ct_color
*next
;
4238 /* The bucket vector size to use. Must be prime. */
4242 /* Value is a hash of the RGB color given by R, G, and B. */
4244 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
4246 /* The color hash table. */
4248 struct ct_color
**ct_table
;
4250 /* Number of entries in the color table. */
4252 int ct_colors_allocated
;
4254 /* Initialize the color table. */
4259 int size
= CT_SIZE
* sizeof (*ct_table
);
4260 ct_table
= (struct ct_color
**) xmalloc (size
);
4261 bzero (ct_table
, size
);
4262 ct_colors_allocated
= 0;
4266 /* Free memory associated with the color table. */
4272 struct ct_color
*p
, *next
;
4274 for (i
= 0; i
< CT_SIZE
; ++i
)
4275 for (p
= ct_table
[i
]; p
; p
= next
)
4286 /* Value is a pixel color for RGB color R, G, B on frame F. If an
4287 entry for that color already is in the color table, return the
4288 pixel color of that entry. Otherwise, allocate a new color for R,
4289 G, B, and make an entry in the color table. */
4291 static unsigned long
4292 lookup_rgb_color (f
, r
, g
, b
)
4296 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
4297 int i
= hash
% CT_SIZE
;
4299 Display_Info
*dpyinfo
;
4301 /* Handle TrueColor visuals specially, which improves performance by
4302 two orders of magnitude. Freeing colors on TrueColor visuals is
4303 a nop, and pixel colors specify RGB values directly. See also
4304 the Xlib spec, chapter 3.1. */
4305 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
4306 if (dpyinfo
->red_bits
> 0)
4308 unsigned long pr
, pg
, pb
;
4310 /* Apply gamma-correction like normal color allocation does. */
4314 color
.red
= r
, color
.green
= g
, color
.blue
= b
;
4315 gamma_correct (f
, &color
);
4316 r
= color
.red
, g
= color
.green
, b
= color
.blue
;
4319 /* Scale down RGB values to the visual's bits per RGB, and shift
4320 them to the right position in the pixel color. Note that the
4321 original RGB values are 16-bit values, as usual in X. */
4322 pr
= (r
>> (16 - dpyinfo
->red_bits
)) << dpyinfo
->red_offset
;
4323 pg
= (g
>> (16 - dpyinfo
->green_bits
)) << dpyinfo
->green_offset
;
4324 pb
= (b
>> (16 - dpyinfo
->blue_bits
)) << dpyinfo
->blue_offset
;
4326 /* Assemble the pixel color. */
4327 return pr
| pg
| pb
;
4330 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4331 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
4337 #ifdef HAVE_X_WINDOWS
4346 cmap
= FRAME_X_COLORMAP (f
);
4347 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4350 ++ct_colors_allocated
;
4351 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4355 p
->pixel
= color
.pixel
;
4356 p
->next
= ct_table
[i
];
4360 return FRAME_FOREGROUND_PIXEL (f
);
4365 color
= PALETTERGB (r
, g
, b
);
4367 color
= RGB_TO_ULONG (r
, g
, b
);
4368 #endif /* HAVE_NTGUI */
4369 ++ct_colors_allocated
;
4370 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4375 p
->next
= ct_table
[i
];
4377 #endif /* HAVE_X_WINDOWS */
4385 /* Look up pixel color PIXEL which is used on frame F in the color
4386 table. If not already present, allocate it. Value is PIXEL. */
4388 static unsigned long
4389 lookup_pixel_color (f
, pixel
)
4391 unsigned long pixel
;
4393 int i
= pixel
% CT_SIZE
;
4396 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4397 if (p
->pixel
== pixel
)
4406 #ifdef HAVE_X_WINDOWS
4407 cmap
= FRAME_X_COLORMAP (f
);
4408 color
.pixel
= pixel
;
4409 x_query_color (f
, &color
);
4410 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4413 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
4414 color
.pixel
= pixel
;
4415 XQueryColor (NULL
, cmap
, &color
);
4416 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4418 #endif /* HAVE_X_WINDOWS */
4422 ++ct_colors_allocated
;
4424 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4429 p
->next
= ct_table
[i
];
4433 return FRAME_FOREGROUND_PIXEL (f
);
4439 /* Value is a vector of all pixel colors contained in the color table,
4440 allocated via xmalloc. Set *N to the number of colors. */
4442 static unsigned long *
4443 colors_in_color_table (n
)
4448 unsigned long *colors
;
4450 if (ct_colors_allocated
== 0)
4457 colors
= (unsigned long *) xmalloc (ct_colors_allocated
4459 *n
= ct_colors_allocated
;
4461 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
4462 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4463 colors
[j
++] = p
->pixel
;
4469 #else /* COLOR_TABLE_SUPPORT */
4471 static unsigned long
4472 lookup_rgb_color (f
, r
, g
, b
)
4476 unsigned long pixel
;
4479 pixel
= PALETTERGB (r
>> 8, g
>> 8, b
>> 8);
4480 #endif /* HAVE_NTGUI */
4483 pixel
= RGB_TO_ULONG (r
>> 8, g
>> 8, b
>> 8);
4484 #endif /* HAVE_NS */
4492 #endif /* COLOR_TABLE_SUPPORT */
4495 /***********************************************************************
4497 ***********************************************************************/
4499 static XColor
*x_to_xcolors
P_ ((struct frame
*, struct image
*, int));
4500 static void x_from_xcolors
P_ ((struct frame
*, struct image
*, XColor
*));
4501 static void x_detect_edges
P_ ((struct frame
*, struct image
*, int[9], int));
4504 static void XPutPixel (XImagePtr
, int, int, COLORREF
);
4505 #endif /* HAVE_NTGUI */
4507 /* Non-zero means draw a cross on images having `:conversion
4510 int cross_disabled_images
;
4512 /* Edge detection matrices for different edge-detection
4515 static int emboss_matrix
[9] = {
4517 2, -1, 0, /* y - 1 */
4519 0, 1, -2 /* y + 1 */
4522 static int laplace_matrix
[9] = {
4524 1, 0, 0, /* y - 1 */
4526 0, 0, -1 /* y + 1 */
4529 /* Value is the intensity of the color whose red/green/blue values
4532 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
4535 /* On frame F, return an array of XColor structures describing image
4536 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
4537 non-zero means also fill the red/green/blue members of the XColor
4538 structures. Value is a pointer to the array of XColors structures,
4539 allocated with xmalloc; it must be freed by the caller. */
4542 x_to_xcolors (f
, img
, rgb_p
)
4549 XImagePtr_or_DC ximg
;
4553 #endif /* HAVE_NTGUI */
4555 colors
= (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *colors
);
4558 /* Get the X image IMG->pixmap. */
4559 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
4560 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4562 /* Load the image into a memory device context. */
4563 hdc
= get_frame_dc (f
);
4564 ximg
= CreateCompatibleDC (hdc
);
4565 release_frame_dc (f
, hdc
);
4566 prev
= SelectObject (ximg
, img
->pixmap
);
4567 #endif /* HAVE_NTGUI */
4569 /* Fill the `pixel' members of the XColor array. I wished there
4570 were an easy and portable way to circumvent XGetPixel. */
4572 for (y
= 0; y
< img
->height
; ++y
)
4576 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
4577 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4578 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4580 x_query_colors (f
, row
, img
->width
);
4584 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4586 /* W32_TODO: palette support needed here? */
4587 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4590 p
->red
= RED16_FROM_ULONG (p
->pixel
);
4591 p
->green
= GREEN16_FROM_ULONG (p
->pixel
);
4592 p
->blue
= BLUE16_FROM_ULONG (p
->pixel
);
4595 #endif /* HAVE_X_WINDOWS */
4598 Destroy_Image (ximg
, prev
);
4605 /* Put a pixel of COLOR at position X, Y in XIMG. XIMG must have been
4606 created with CreateDIBSection, with the pointer to the bit values
4607 stored in ximg->data. */
4610 XPutPixel (ximg
, x
, y
, color
)
4615 int width
= ximg
->info
.bmiHeader
.biWidth
;
4616 int height
= ximg
->info
.bmiHeader
.biHeight
;
4617 unsigned char * pixel
;
4619 /* True color images. */
4620 if (ximg
->info
.bmiHeader
.biBitCount
== 24)
4622 int rowbytes
= width
* 3;
4623 /* Ensure scanlines are aligned on 4 byte boundaries. */
4625 rowbytes
+= 4 - (rowbytes
% 4);
4627 pixel
= ximg
->data
+ y
* rowbytes
+ x
* 3;
4628 /* Windows bitmaps are in BGR order. */
4629 *pixel
= GetBValue (color
);
4630 *(pixel
+ 1) = GetGValue (color
);
4631 *(pixel
+ 2) = GetRValue (color
);
4633 /* Monochrome images. */
4634 else if (ximg
->info
.bmiHeader
.biBitCount
== 1)
4636 int rowbytes
= width
/ 8;
4637 /* Ensure scanlines are aligned on 4 byte boundaries. */
4639 rowbytes
+= 4 - (rowbytes
% 4);
4640 pixel
= ximg
->data
+ y
* rowbytes
+ x
/ 8;
4641 /* Filter out palette info. */
4642 if (color
& 0x00ffffff)
4643 *pixel
= *pixel
| (1 << x
% 8);
4645 *pixel
= *pixel
& ~(1 << x
% 8);
4648 image_error ("XPutPixel: palette image not supported", Qnil
, Qnil
);
4651 #endif /* HAVE_NTGUI */
4653 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
4654 RGB members are set. F is the frame on which this all happens.
4655 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
4658 x_from_xcolors (f
, img
, colors
)
4664 XImagePtr oimg
= NULL
;
4668 init_color_table ();
4670 x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
4673 for (y
= 0; y
< img
->height
; ++y
)
4674 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4676 unsigned long pixel
;
4677 pixel
= lookup_rgb_color (f
, p
->red
, p
->green
, p
->blue
);
4678 XPutPixel (oimg
, x
, y
, pixel
);
4682 x_clear_image_1 (f
, img
, 1, 0, 1);
4684 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
4685 x_destroy_x_image (oimg
);
4686 img
->pixmap
= pixmap
;
4687 #ifdef COLOR_TABLE_SUPPORT
4688 img
->colors
= colors_in_color_table (&img
->ncolors
);
4689 free_color_table ();
4690 #endif /* COLOR_TABLE_SUPPORT */
4694 /* On frame F, perform edge-detection on image IMG.
4696 MATRIX is a nine-element array specifying the transformation
4697 matrix. See emboss_matrix for an example.
4699 COLOR_ADJUST is a color adjustment added to each pixel of the
4703 x_detect_edges (f
, img
, matrix
, color_adjust
)
4706 int matrix
[9], color_adjust
;
4708 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4712 for (i
= sum
= 0; i
< 9; ++i
)
4713 sum
+= eabs (matrix
[i
]);
4715 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
4717 new = (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *new);
4719 for (y
= 0; y
< img
->height
; ++y
)
4721 p
= COLOR (new, 0, y
);
4722 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4723 p
= COLOR (new, img
->width
- 1, y
);
4724 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4727 for (x
= 1; x
< img
->width
- 1; ++x
)
4729 p
= COLOR (new, x
, 0);
4730 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4731 p
= COLOR (new, x
, img
->height
- 1);
4732 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4735 for (y
= 1; y
< img
->height
- 1; ++y
)
4737 p
= COLOR (new, 1, y
);
4739 for (x
= 1; x
< img
->width
- 1; ++x
, ++p
)
4741 int r
, g
, b
, y1
, x1
;
4744 for (y1
= y
- 1; y1
< y
+ 2; ++y1
)
4745 for (x1
= x
- 1; x1
< x
+ 2; ++x1
, ++i
)
4748 XColor
*t
= COLOR (colors
, x1
, y1
);
4749 r
+= matrix
[i
] * t
->red
;
4750 g
+= matrix
[i
] * t
->green
;
4751 b
+= matrix
[i
] * t
->blue
;
4754 r
= (r
/ sum
+ color_adjust
) & 0xffff;
4755 g
= (g
/ sum
+ color_adjust
) & 0xffff;
4756 b
= (b
/ sum
+ color_adjust
) & 0xffff;
4757 p
->red
= p
->green
= p
->blue
= COLOR_INTENSITY (r
, g
, b
);
4762 x_from_xcolors (f
, img
, new);
4768 /* Perform the pre-defined `emboss' edge-detection on image IMG
4776 x_detect_edges (f
, img
, emboss_matrix
, 0xffff / 2);
4780 /* Transform image IMG which is used on frame F with a Laplace
4781 edge-detection algorithm. The result is an image that can be used
4782 to draw disabled buttons, for example. */
4789 x_detect_edges (f
, img
, laplace_matrix
, 45000);
4793 /* Perform edge-detection on image IMG on frame F, with specified
4794 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
4796 MATRIX must be either
4798 - a list of at least 9 numbers in row-major form
4799 - a vector of at least 9 numbers
4801 COLOR_ADJUST nil means use a default; otherwise it must be a
4805 x_edge_detection (f
, img
, matrix
, color_adjust
)
4808 Lisp_Object matrix
, color_adjust
;
4816 i
< 9 && CONSP (matrix
) && NUMBERP (XCAR (matrix
));
4817 ++i
, matrix
= XCDR (matrix
))
4818 trans
[i
] = XFLOATINT (XCAR (matrix
));
4820 else if (VECTORP (matrix
) && ASIZE (matrix
) >= 9)
4822 for (i
= 0; i
< 9 && NUMBERP (AREF (matrix
, i
)); ++i
)
4823 trans
[i
] = XFLOATINT (AREF (matrix
, i
));
4826 if (NILP (color_adjust
))
4827 color_adjust
= make_number (0xffff / 2);
4829 if (i
== 9 && NUMBERP (color_adjust
))
4830 x_detect_edges (f
, img
, trans
, (int) XFLOATINT (color_adjust
));
4834 /* Transform image IMG on frame F so that it looks disabled. */
4837 x_disable_image (f
, img
)
4841 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
4843 int n_planes
= dpyinfo
->n_planes
* dpyinfo
->n_cbits
;
4845 int n_planes
= dpyinfo
->n_planes
;
4846 #endif /* HAVE_NTGUI */
4850 /* Color (or grayscale). Convert to gray, and equalize. Just
4851 drawing such images with a stipple can look very odd, so
4852 we're using this method instead. */
4853 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4855 const int h
= 15000;
4856 const int l
= 30000;
4858 for (p
= colors
, end
= colors
+ img
->width
* img
->height
;
4862 int i
= COLOR_INTENSITY (p
->red
, p
->green
, p
->blue
);
4863 int i2
= (0xffff - h
- l
) * i
/ 0xffff + l
;
4864 p
->red
= p
->green
= p
->blue
= i2
;
4867 x_from_xcolors (f
, img
, colors
);
4870 /* Draw a cross over the disabled image, if we must or if we
4872 if (n_planes
< 2 || cross_disabled_images
)
4875 Display
*dpy
= FRAME_X_DISPLAY (f
);
4878 #ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
4880 #define MaskForeground(f) WHITE_PIX_DEFAULT (f)
4882 gc
= XCreateGC (dpy
, img
->pixmap
, 0, NULL
);
4883 XSetForeground (dpy
, gc
, BLACK_PIX_DEFAULT (f
));
4884 XDrawLine (dpy
, img
->pixmap
, gc
, 0, 0,
4885 img
->width
- 1, img
->height
- 1);
4886 XDrawLine (dpy
, img
->pixmap
, gc
, 0, img
->height
- 1,
4892 gc
= XCreateGC (dpy
, img
->mask
, 0, NULL
);
4893 XSetForeground (dpy
, gc
, MaskForeground (f
));
4894 XDrawLine (dpy
, img
->mask
, gc
, 0, 0,
4895 img
->width
- 1, img
->height
- 1);
4896 XDrawLine (dpy
, img
->mask
, gc
, 0, img
->height
- 1,
4900 #endif /* !HAVE_NS */
4905 hdc
= get_frame_dc (f
);
4906 bmpdc
= CreateCompatibleDC (hdc
);
4907 release_frame_dc (f
, hdc
);
4909 prev
= SelectObject (bmpdc
, img
->pixmap
);
4911 SetTextColor (bmpdc
, BLACK_PIX_DEFAULT (f
));
4912 MoveToEx (bmpdc
, 0, 0, NULL
);
4913 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
4914 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
4915 LineTo (bmpdc
, img
->width
- 1, 0);
4919 SelectObject (bmpdc
, img
->mask
);
4920 SetTextColor (bmpdc
, WHITE_PIX_DEFAULT (f
));
4921 MoveToEx (bmpdc
, 0, 0, NULL
);
4922 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
4923 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
4924 LineTo (bmpdc
, img
->width
- 1, 0);
4926 SelectObject (bmpdc
, prev
);
4928 #endif /* HAVE_NTGUI */
4933 /* Build a mask for image IMG which is used on frame F. FILE is the
4934 name of an image file, for error messages. HOW determines how to
4935 determine the background color of IMG. If it is a list '(R G B)',
4936 with R, G, and B being integers >= 0, take that as the color of the
4937 background. Otherwise, determine the background color of IMG
4938 heuristically. Value is non-zero if successful. */
4941 x_build_heuristic_mask (f
, img
, how
)
4946 XImagePtr_or_DC ximg
;
4954 #endif /* HAVE_NTGUI */
4955 int x
, y
, rc
, use_img_background
;
4956 unsigned long bg
= 0;
4960 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4961 img
->mask
= NO_PIXMAP
;
4962 img
->background_transparent_valid
= 0;
4967 /* Create an image and pixmap serving as mask. */
4968 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
4969 &mask_img
, &img
->mask
);
4972 #endif /* !HAVE_NS */
4974 /* Get the X image of IMG->pixmap. */
4975 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
, 0, 0,
4976 img
->width
, img
->height
,
4979 /* Create the bit array serving as mask. */
4980 row_width
= (img
->width
+ 7) / 8;
4981 mask_img
= xmalloc (row_width
* img
->height
);
4982 bzero (mask_img
, row_width
* img
->height
);
4984 /* Create a memory device context for IMG->pixmap. */
4985 frame_dc
= get_frame_dc (f
);
4986 ximg
= CreateCompatibleDC (frame_dc
);
4987 release_frame_dc (f
, frame_dc
);
4988 prev
= SelectObject (ximg
, img
->pixmap
);
4989 #endif /* HAVE_NTGUI */
4991 /* Determine the background color of ximg. If HOW is `(R G B)'
4992 take that as color. Otherwise, use the image's background color. */
4993 use_img_background
= 1;
4999 for (i
= 0; i
< 3 && CONSP (how
) && NATNUMP (XCAR (how
)); ++i
)
5001 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
5005 if (i
== 3 && NILP (how
))
5007 char color_name
[30];
5008 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
5011 0x00ffffff & /* Filter out palette info. */
5012 #endif /* HAVE_NTGUI */
5013 x_alloc_image_color (f
, img
, build_string (color_name
), 0));
5014 use_img_background
= 0;
5018 if (use_img_background
)
5019 bg
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
5021 /* Set all bits in mask_img to 1 whose color in ximg is different
5022 from the background color bg. */
5024 for (y
= 0; y
< img
->height
; ++y
)
5025 for (x
= 0; x
< img
->width
; ++x
)
5027 XPutPixel (mask_img
, x
, y
, (XGetPixel (ximg
, x
, y
) != bg
5028 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
));
5030 if (XGetPixel (ximg
, x
, y
) == bg
)
5031 ns_set_alpha(ximg
, x
, y
, 0);
5032 #endif /* HAVE_NS */
5034 /* Fill in the background_transparent field while we have the mask handy. */
5035 image_background_transparent (img
, f
, mask_img
);
5037 /* Put mask_img into img->mask. */
5038 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
5039 x_destroy_x_image (mask_img
);
5040 #endif /* !HAVE_NS */
5042 for (y
= 0; y
< img
->height
; ++y
)
5043 for (x
= 0; x
< img
->width
; ++x
)
5045 COLORREF p
= GetPixel (ximg
, x
, y
);
5047 mask_img
[y
* row_width
+ x
/ 8] |= 1 << (x
% 8);
5050 /* Create the mask image. */
5051 img
->mask
= w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
,
5053 /* Fill in the background_transparent field while we have the mask handy. */
5054 SelectObject (ximg
, img
->mask
);
5055 image_background_transparent (img
, f
, ximg
);
5057 /* Was: x_destroy_x_image ((XImagePtr )mask_img); which seems bogus ++kfs */
5059 #endif /* HAVE_NTGUI */
5061 Destroy_Image (ximg
, prev
);
5067 /***********************************************************************
5068 PBM (mono, gray, color)
5069 ***********************************************************************/
5071 static int pbm_image_p
P_ ((Lisp_Object object
));
5072 static int pbm_load
P_ ((struct frame
*f
, struct image
*img
));
5073 static int pbm_scan_number
P_ ((unsigned char **, unsigned char *));
5075 /* The symbol `pbm' identifying images of this type. */
5079 /* Indices of image specification fields in gs_format, below. */
5081 enum pbm_keyword_index
5097 /* Vector of image_keyword structures describing the format
5098 of valid user-defined image specifications. */
5100 static const struct image_keyword pbm_format
[PBM_LAST
] =
5102 {":type", IMAGE_SYMBOL_VALUE
, 1},
5103 {":file", IMAGE_STRING_VALUE
, 0},
5104 {":data", IMAGE_STRING_VALUE
, 0},
5105 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5106 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5107 {":relief", IMAGE_INTEGER_VALUE
, 0},
5108 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5109 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5110 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5111 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
5112 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
5115 /* Structure describing the image type `pbm'. */
5117 static struct image_type pbm_type
=
5127 /* Return non-zero if OBJECT is a valid PBM image specification. */
5130 pbm_image_p (object
)
5133 struct image_keyword fmt
[PBM_LAST
];
5135 bcopy (pbm_format
, fmt
, sizeof fmt
);
5137 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
))
5140 /* Must specify either :data or :file. */
5141 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
5145 /* Scan a decimal number from *S and return it. Advance *S while
5146 reading the number. END is the end of the string. Value is -1 at
5150 pbm_scan_number (s
, end
)
5151 unsigned char **s
, *end
;
5153 int c
= 0, val
= -1;
5157 /* Skip white-space. */
5158 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
5163 /* Skip comment to end of line. */
5164 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
5167 else if (isdigit (c
))
5169 /* Read decimal number. */
5171 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
5172 val
= 10 * val
+ c
- '0';
5184 #if 0 /* Unused. ++kfs */
5186 /* Read FILE into memory. Value is a pointer to a buffer allocated
5187 with xmalloc holding FILE's contents. Value is null if an error
5188 occurred. *SIZE is set to the size of the file. */
5191 pbm_read_file (file
, size
)
5199 if (stat (SDATA (file
), &st
) == 0
5200 && (fp
= fopen (SDATA (file
), "rb")) != NULL
5201 && (buf
= (char *) xmalloc (st
.st_size
),
5202 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
5221 #endif /* HAVE_NTGUI */
5223 /* Load PBM image IMG for use on frame F. */
5231 int width
, height
, max_color_idx
= 0;
5233 Lisp_Object file
, specified_file
;
5234 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
5235 struct gcpro gcpro1
;
5236 unsigned char *contents
= NULL
;
5237 unsigned char *end
, *p
;
5240 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5244 if (STRINGP (specified_file
))
5246 file
= x_find_image_file (specified_file
);
5247 if (!STRINGP (file
))
5249 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5254 contents
= slurp_file (SDATA (file
), &size
);
5255 if (contents
== NULL
)
5257 image_error ("Error reading `%s'", file
, Qnil
);
5263 end
= contents
+ size
;
5268 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5270 end
= p
+ SBYTES (data
);
5273 /* Check magic number. */
5274 if (end
- p
< 2 || *p
++ != 'P')
5276 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5286 raw_p
= 0, type
= PBM_MONO
;
5290 raw_p
= 0, type
= PBM_GRAY
;
5294 raw_p
= 0, type
= PBM_COLOR
;
5298 raw_p
= 1, type
= PBM_MONO
;
5302 raw_p
= 1, type
= PBM_GRAY
;
5306 raw_p
= 1, type
= PBM_COLOR
;
5310 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5314 /* Read width, height, maximum color-component. Characters
5315 starting with `#' up to the end of a line are ignored. */
5316 width
= pbm_scan_number (&p
, end
);
5317 height
= pbm_scan_number (&p
, end
);
5319 if (type
!= PBM_MONO
)
5321 max_color_idx
= pbm_scan_number (&p
, end
);
5322 if (max_color_idx
> 65535 || max_color_idx
< 0)
5324 image_error ("Unsupported maximum PBM color value", Qnil
, Qnil
);
5329 if (!check_image_size (f
, width
, height
))
5331 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
5335 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
5336 &ximg
, &img
->pixmap
))
5339 /* Initialize the color hash table. */
5340 init_color_table ();
5342 if (type
== PBM_MONO
)
5345 struct image_keyword fmt
[PBM_LAST
];
5346 unsigned long fg
= FRAME_FOREGROUND_PIXEL (f
);
5347 unsigned long bg
= FRAME_BACKGROUND_PIXEL (f
);
5349 /* Parse the image specification. */
5350 bcopy (pbm_format
, fmt
, sizeof fmt
);
5351 parse_image_spec (img
->spec
, fmt
, PBM_LAST
, Qpbm
);
5353 /* Get foreground and background colors, maybe allocate colors. */
5354 if (fmt
[PBM_FOREGROUND
].count
5355 && STRINGP (fmt
[PBM_FOREGROUND
].value
))
5356 fg
= x_alloc_image_color (f
, img
, fmt
[PBM_FOREGROUND
].value
, fg
);
5357 if (fmt
[PBM_BACKGROUND
].count
5358 && STRINGP (fmt
[PBM_BACKGROUND
].value
))
5360 bg
= x_alloc_image_color (f
, img
, fmt
[PBM_BACKGROUND
].value
, bg
);
5361 img
->background
= bg
;
5362 img
->background_valid
= 1;
5365 for (y
= 0; y
< height
; ++y
)
5366 for (x
= 0; x
< width
; ++x
)
5374 x_destroy_x_image (ximg
);
5375 x_clear_image (f
, img
);
5376 image_error ("Invalid image size in image `%s'",
5386 g
= pbm_scan_number (&p
, end
);
5388 XPutPixel (ximg
, x
, y
, g
? fg
: bg
);
5393 int expected_size
= height
* width
;
5394 if (max_color_idx
> 255)
5396 if (type
== PBM_COLOR
)
5399 if (raw_p
&& p
+ expected_size
> end
)
5401 x_destroy_x_image (ximg
);
5402 x_clear_image (f
, img
);
5403 image_error ("Invalid image size in image `%s'",
5408 for (y
= 0; y
< height
; ++y
)
5409 for (x
= 0; x
< width
; ++x
)
5413 if (type
== PBM_GRAY
&& raw_p
)
5416 if (max_color_idx
> 255)
5417 r
= g
= b
= r
* 256 + *p
++;
5419 else if (type
== PBM_GRAY
)
5420 r
= g
= b
= pbm_scan_number (&p
, end
);
5424 if (max_color_idx
> 255)
5427 if (max_color_idx
> 255)
5430 if (max_color_idx
> 255)
5435 r
= pbm_scan_number (&p
, end
);
5436 g
= pbm_scan_number (&p
, end
);
5437 b
= pbm_scan_number (&p
, end
);
5440 if (r
< 0 || g
< 0 || b
< 0)
5442 x_destroy_x_image (ximg
);
5443 image_error ("Invalid pixel value in image `%s'",
5448 /* RGB values are now in the range 0..max_color_idx.
5449 Scale this to the range 0..0xffff supported by X. */
5450 r
= (double) r
* 65535 / max_color_idx
;
5451 g
= (double) g
* 65535 / max_color_idx
;
5452 b
= (double) b
* 65535 / max_color_idx
;
5453 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
5457 #ifdef COLOR_TABLE_SUPPORT
5458 /* Store in IMG->colors the colors allocated for the image, and
5459 free the color table. */
5460 img
->colors
= colors_in_color_table (&img
->ncolors
);
5461 free_color_table ();
5462 #endif /* COLOR_TABLE_SUPPORT */
5465 img
->height
= height
;
5467 /* Maybe fill in the background field while we have ximg handy. */
5469 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
5470 /* Casting avoids a GCC warning. */
5471 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
5473 /* Put the image into a pixmap. */
5474 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
5475 x_destroy_x_image (ximg
);
5477 /* X and W32 versions did it here, MAC version above. ++kfs
5479 img->height = height; */
5487 /***********************************************************************
5489 ***********************************************************************/
5491 #if defined (HAVE_PNG) || defined (HAVE_NS)
5493 /* Function prototypes. */
5495 static int png_image_p
P_ ((Lisp_Object object
));
5496 static int png_load
P_ ((struct frame
*f
, struct image
*img
));
5498 /* The symbol `png' identifying images of this type. */
5502 /* Indices of image specification fields in png_format, below. */
5504 enum png_keyword_index
5519 /* Vector of image_keyword structures describing the format
5520 of valid user-defined image specifications. */
5522 static const struct image_keyword png_format
[PNG_LAST
] =
5524 {":type", IMAGE_SYMBOL_VALUE
, 1},
5525 {":data", IMAGE_STRING_VALUE
, 0},
5526 {":file", IMAGE_STRING_VALUE
, 0},
5527 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5528 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5529 {":relief", IMAGE_INTEGER_VALUE
, 0},
5530 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5531 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5532 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5533 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
5536 /* Structure describing the image type `png'. */
5538 static struct image_type png_type
=
5547 /* Return non-zero if OBJECT is a valid PNG image specification. */
5550 png_image_p (object
)
5553 struct image_keyword fmt
[PNG_LAST
];
5554 bcopy (png_format
, fmt
, sizeof fmt
);
5556 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
5559 /* Must specify either the :data or :file keyword. */
5560 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
5563 #endif /* HAVE_PNG || HAVE_NS */
5569 /* PNG library details. */
5571 DEF_IMGLIB_FN (png_get_io_ptr
);
5572 DEF_IMGLIB_FN (png_sig_cmp
);
5573 DEF_IMGLIB_FN (png_create_read_struct
);
5574 DEF_IMGLIB_FN (png_create_info_struct
);
5575 DEF_IMGLIB_FN (png_destroy_read_struct
);
5576 DEF_IMGLIB_FN (png_set_read_fn
);
5577 DEF_IMGLIB_FN (png_set_sig_bytes
);
5578 DEF_IMGLIB_FN (png_read_info
);
5579 DEF_IMGLIB_FN (png_get_IHDR
);
5580 DEF_IMGLIB_FN (png_get_valid
);
5581 DEF_IMGLIB_FN (png_set_strip_16
);
5582 DEF_IMGLIB_FN (png_set_expand
);
5583 DEF_IMGLIB_FN (png_set_gray_to_rgb
);
5584 DEF_IMGLIB_FN (png_set_background
);
5585 DEF_IMGLIB_FN (png_get_bKGD
);
5586 DEF_IMGLIB_FN (png_read_update_info
);
5587 DEF_IMGLIB_FN (png_get_channels
);
5588 DEF_IMGLIB_FN (png_get_rowbytes
);
5589 DEF_IMGLIB_FN (png_read_image
);
5590 DEF_IMGLIB_FN (png_read_end
);
5591 DEF_IMGLIB_FN (png_error
);
5594 init_png_functions (Lisp_Object libraries
)
5598 /* Try loading libpng under probable names. */
5599 if (!(library
= w32_delayed_load (libraries
, Qpng
)))
5602 LOAD_IMGLIB_FN (library
, png_get_io_ptr
);
5603 LOAD_IMGLIB_FN (library
, png_sig_cmp
);
5604 LOAD_IMGLIB_FN (library
, png_create_read_struct
);
5605 LOAD_IMGLIB_FN (library
, png_create_info_struct
);
5606 LOAD_IMGLIB_FN (library
, png_destroy_read_struct
);
5607 LOAD_IMGLIB_FN (library
, png_set_read_fn
);
5608 LOAD_IMGLIB_FN (library
, png_set_sig_bytes
);
5609 LOAD_IMGLIB_FN (library
, png_read_info
);
5610 LOAD_IMGLIB_FN (library
, png_get_IHDR
);
5611 LOAD_IMGLIB_FN (library
, png_get_valid
);
5612 LOAD_IMGLIB_FN (library
, png_set_strip_16
);
5613 LOAD_IMGLIB_FN (library
, png_set_expand
);
5614 LOAD_IMGLIB_FN (library
, png_set_gray_to_rgb
);
5615 LOAD_IMGLIB_FN (library
, png_set_background
);
5616 LOAD_IMGLIB_FN (library
, png_get_bKGD
);
5617 LOAD_IMGLIB_FN (library
, png_read_update_info
);
5618 LOAD_IMGLIB_FN (library
, png_get_channels
);
5619 LOAD_IMGLIB_FN (library
, png_get_rowbytes
);
5620 LOAD_IMGLIB_FN (library
, png_read_image
);
5621 LOAD_IMGLIB_FN (library
, png_read_end
);
5622 LOAD_IMGLIB_FN (library
, png_error
);
5627 #define fn_png_get_io_ptr png_get_io_ptr
5628 #define fn_png_sig_cmp png_sig_cmp
5629 #define fn_png_create_read_struct png_create_read_struct
5630 #define fn_png_create_info_struct png_create_info_struct
5631 #define fn_png_destroy_read_struct png_destroy_read_struct
5632 #define fn_png_set_read_fn png_set_read_fn
5633 #define fn_png_set_sig_bytes png_set_sig_bytes
5634 #define fn_png_read_info png_read_info
5635 #define fn_png_get_IHDR png_get_IHDR
5636 #define fn_png_get_valid png_get_valid
5637 #define fn_png_set_strip_16 png_set_strip_16
5638 #define fn_png_set_expand png_set_expand
5639 #define fn_png_set_gray_to_rgb png_set_gray_to_rgb
5640 #define fn_png_set_background png_set_background
5641 #define fn_png_get_bKGD png_get_bKGD
5642 #define fn_png_read_update_info png_read_update_info
5643 #define fn_png_get_channels png_get_channels
5644 #define fn_png_get_rowbytes png_get_rowbytes
5645 #define fn_png_read_image png_read_image
5646 #define fn_png_read_end png_read_end
5647 #define fn_png_error png_error
5649 #endif /* HAVE_NTGUI */
5651 /* Error and warning handlers installed when the PNG library
5655 my_png_error (png_ptr
, msg
)
5656 png_struct
*png_ptr
;
5659 xassert (png_ptr
!= NULL
);
5660 /* Avoid compiler warning about deprecated direct access to
5661 png_ptr's fields in libpng versions 1.4.x. */
5662 image_error ("PNG error: %s", build_string (msg
), Qnil
);
5663 longjmp (png_ptr
->jmpbuf
, 1);
5668 my_png_warning (png_ptr
, msg
)
5669 png_struct
*png_ptr
;
5672 xassert (png_ptr
!= NULL
);
5673 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
5676 /* Memory source for PNG decoding. */
5678 struct png_memory_storage
5680 unsigned char *bytes
; /* The data */
5681 size_t len
; /* How big is it? */
5682 int index
; /* Where are we? */
5686 /* Function set as reader function when reading PNG image from memory.
5687 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5688 bytes from the input to DATA. */
5691 png_read_from_memory (png_ptr
, data
, length
)
5692 png_structp png_ptr
;
5696 struct png_memory_storage
*tbr
5697 = (struct png_memory_storage
*) fn_png_get_io_ptr (png_ptr
);
5699 if (length
> tbr
->len
- tbr
->index
)
5700 fn_png_error (png_ptr
, "Read error");
5702 bcopy (tbr
->bytes
+ tbr
->index
, data
, length
);
5703 tbr
->index
= tbr
->index
+ length
;
5707 /* Function set as reader function when reading PNG image from a file.
5708 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5709 bytes from the input to DATA. */
5712 png_read_from_file (png_ptr
, data
, length
)
5713 png_structp png_ptr
;
5717 FILE *fp
= (FILE *) fn_png_get_io_ptr (png_ptr
);
5719 if (fread (data
, 1, length
, fp
) < length
)
5720 fn_png_error (png_ptr
, "Read error");
5724 /* Load PNG image IMG for use on frame F. Value is non-zero if
5732 Lisp_Object file
, specified_file
;
5733 Lisp_Object specified_data
;
5735 XImagePtr ximg
, mask_img
= NULL
;
5736 struct gcpro gcpro1
;
5737 png_struct
*png_ptr
= NULL
;
5738 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
5739 FILE *volatile fp
= NULL
;
5741 png_byte
* volatile pixels
= NULL
;
5742 png_byte
** volatile rows
= NULL
;
5743 png_uint_32 width
, height
;
5744 int bit_depth
, color_type
, interlace_type
;
5746 png_uint_32 row_bytes
;
5748 struct png_memory_storage tbr
; /* Data to be read */
5750 /* Find out what file to load. */
5751 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5752 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5756 if (NILP (specified_data
))
5758 file
= x_find_image_file (specified_file
);
5759 if (!STRINGP (file
))
5761 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5766 /* Open the image file. */
5767 fp
= fopen (SDATA (file
), "rb");
5770 image_error ("Cannot open image file `%s'", file
, Qnil
);
5775 /* Check PNG signature. */
5776 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
5777 || fn_png_sig_cmp (sig
, 0, sizeof sig
))
5779 image_error ("Not a PNG file: `%s'", file
, Qnil
);
5787 /* Read from memory. */
5788 tbr
.bytes
= SDATA (specified_data
);
5789 tbr
.len
= SBYTES (specified_data
);
5792 /* Check PNG signature. */
5793 if (tbr
.len
< sizeof sig
5794 || fn_png_sig_cmp (tbr
.bytes
, 0, sizeof sig
))
5796 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
5801 /* Need to skip past the signature. */
5802 tbr
.bytes
+= sizeof (sig
);
5805 /* Initialize read and info structs for PNG lib. Casting return
5806 value avoids a GCC warning on W32. */
5807 png_ptr
= (png_structp
)fn_png_create_read_struct (PNG_LIBPNG_VER_STRING
,
5812 if (fp
) fclose (fp
);
5817 /* Casting return value avoids a GCC warning on W32. */
5818 info_ptr
= (png_infop
)fn_png_create_info_struct (png_ptr
);
5821 fn_png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
5822 if (fp
) fclose (fp
);
5827 /* Casting return value avoids a GCC warning on W32. */
5828 end_info
= (png_infop
)fn_png_create_info_struct (png_ptr
);
5831 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
5832 if (fp
) fclose (fp
);
5837 /* Set error jump-back. We come back here when the PNG library
5838 detects an error. */
5839 if (setjmp (png_ptr
->jmpbuf
))
5843 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
5846 if (fp
) fclose (fp
);
5851 /* Read image info. */
5852 if (!NILP (specified_data
))
5853 fn_png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
5855 fn_png_set_read_fn (png_ptr
, (void *) fp
, png_read_from_file
);
5857 fn_png_set_sig_bytes (png_ptr
, sizeof sig
);
5858 fn_png_read_info (png_ptr
, info_ptr
);
5859 fn_png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
5860 &interlace_type
, NULL
, NULL
);
5862 if (!check_image_size (f
, width
, height
))
5864 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
5867 /* If image contains simply transparency data, we prefer to
5868 construct a clipping mask. */
5869 if (fn_png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
5874 /* This function is easier to write if we only have to handle
5875 one data format: RGB or RGBA with 8 bits per channel. Let's
5876 transform other formats into that format. */
5878 /* Strip more than 8 bits per channel. */
5879 if (bit_depth
== 16)
5880 fn_png_set_strip_16 (png_ptr
);
5882 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
5884 fn_png_set_expand (png_ptr
);
5886 /* Convert grayscale images to RGB. */
5887 if (color_type
== PNG_COLOR_TYPE_GRAY
5888 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
5889 fn_png_set_gray_to_rgb (png_ptr
);
5891 /* Handle alpha channel by combining the image with a background
5892 color. Do this only if a real alpha channel is supplied. For
5893 simple transparency, we prefer a clipping mask. */
5896 /* png_color_16 *image_bg; */
5897 Lisp_Object specified_bg
5898 = image_spec_value (img
->spec
, QCbackground
, NULL
);
5899 int shift
= (bit_depth
== 16) ? 0 : 8;
5901 if (STRINGP (specified_bg
))
5902 /* The user specified `:background', use that. */
5905 if (x_defined_color (f
, SDATA (specified_bg
), &color
, 0))
5907 png_color_16 user_bg
;
5909 bzero (&user_bg
, sizeof user_bg
);
5910 user_bg
.red
= color
.red
>> shift
;
5911 user_bg
.green
= color
.green
>> shift
;
5912 user_bg
.blue
= color
.blue
>> shift
;
5914 fn_png_set_background (png_ptr
, &user_bg
,
5915 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
5920 /* We use the current frame background, ignoring any default
5921 background color set by the image. */
5922 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
5924 png_color_16 frame_background
;
5926 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
5927 x_query_color (f
, &color
);
5929 bzero (&frame_background
, sizeof frame_background
);
5930 frame_background
.red
= color
.red
>> shift
;
5931 frame_background
.green
= color
.green
>> shift
;
5932 frame_background
.blue
= color
.blue
>> shift
;
5933 #endif /* HAVE_X_WINDOWS */
5935 fn_png_set_background (png_ptr
, &frame_background
,
5936 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
5940 /* Update info structure. */
5941 fn_png_read_update_info (png_ptr
, info_ptr
);
5943 /* Get number of channels. Valid values are 1 for grayscale images
5944 and images with a palette, 2 for grayscale images with transparency
5945 information (alpha channel), 3 for RGB images, and 4 for RGB
5946 images with alpha channel, i.e. RGBA. If conversions above were
5947 sufficient we should only have 3 or 4 channels here. */
5948 channels
= fn_png_get_channels (png_ptr
, info_ptr
);
5949 xassert (channels
== 3 || channels
== 4);
5951 /* Number of bytes needed for one row of the image. */
5952 row_bytes
= fn_png_get_rowbytes (png_ptr
, info_ptr
);
5954 /* Allocate memory for the image. */
5955 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
5956 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
5957 for (i
= 0; i
< height
; ++i
)
5958 rows
[i
] = pixels
+ i
* row_bytes
;
5960 /* Read the entire image. */
5961 fn_png_read_image (png_ptr
, rows
);
5962 fn_png_read_end (png_ptr
, info_ptr
);
5969 /* Create the X image and pixmap. */
5970 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
5974 /* Create an image and pixmap serving as mask if the PNG image
5975 contains an alpha channel. */
5978 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
5979 &mask_img
, &img
->mask
))
5981 x_destroy_x_image (ximg
);
5982 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
5983 img
->pixmap
= NO_PIXMAP
;
5987 /* Fill the X image and mask from PNG data. */
5988 init_color_table ();
5990 for (y
= 0; y
< height
; ++y
)
5992 png_byte
*p
= rows
[y
];
5994 for (x
= 0; x
< width
; ++x
)
6001 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
6002 /* An alpha channel, aka mask channel, associates variable
6003 transparency with an image. Where other image formats
6004 support binary transparency---fully transparent or fully
6005 opaque---PNG allows up to 254 levels of partial transparency.
6006 The PNG library implements partial transparency by combining
6007 the image with a specified background color.
6009 I'm not sure how to handle this here nicely: because the
6010 background on which the image is displayed may change, for
6011 real alpha channel support, it would be necessary to create
6012 a new image for each possible background.
6014 What I'm doing now is that a mask is created if we have
6015 boolean transparency information. Otherwise I'm using
6016 the frame's background color to combine the image with. */
6021 XPutPixel (mask_img
, x
, y
, *p
> 0 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
);
6027 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6028 /* Set IMG's background color from the PNG image, unless the user
6032 if (fn_png_get_bKGD (png_ptr
, info_ptr
, &bg
))
6034 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
6035 img
->background_valid
= 1;
6039 #ifdef COLOR_TABLE_SUPPORT
6040 /* Remember colors allocated for this image. */
6041 img
->colors
= colors_in_color_table (&img
->ncolors
);
6042 free_color_table ();
6043 #endif /* COLOR_TABLE_SUPPORT */
6046 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
6051 img
->height
= height
;
6053 /* Maybe fill in the background field while we have ximg handy.
6054 Casting avoids a GCC warning. */
6055 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6057 /* Put the image into the pixmap, then free the X image and its buffer. */
6058 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6059 x_destroy_x_image (ximg
);
6061 /* Same for the mask. */
6064 /* Fill in the background_transparent field while we have the
6065 mask handy. Casting avoids a GCC warning. */
6066 image_background_transparent (img
, f
, (XImagePtr_or_DC
)mask_img
);
6068 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
6069 x_destroy_x_image (mask_img
);
6076 #else /* HAVE_PNG */
6080 png_load (struct frame
*f
, struct image
*img
)
6082 return ns_load_image(f
, img
,
6083 image_spec_value (img
->spec
, QCfile
, NULL
),
6084 image_spec_value (img
->spec
, QCdata
, NULL
));
6086 #endif /* HAVE_NS */
6089 #endif /* !HAVE_PNG */
6093 /***********************************************************************
6095 ***********************************************************************/
6097 #if defined (HAVE_JPEG) || defined (HAVE_NS)
6099 static int jpeg_image_p
P_ ((Lisp_Object object
));
6100 static int jpeg_load
P_ ((struct frame
*f
, struct image
*img
));
6102 /* The symbol `jpeg' identifying images of this type. */
6106 /* Indices of image specification fields in gs_format, below. */
6108 enum jpeg_keyword_index
6117 JPEG_HEURISTIC_MASK
,
6123 /* Vector of image_keyword structures describing the format
6124 of valid user-defined image specifications. */
6126 static const struct image_keyword jpeg_format
[JPEG_LAST
] =
6128 {":type", IMAGE_SYMBOL_VALUE
, 1},
6129 {":data", IMAGE_STRING_VALUE
, 0},
6130 {":file", IMAGE_STRING_VALUE
, 0},
6131 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6132 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6133 {":relief", IMAGE_INTEGER_VALUE
, 0},
6134 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6135 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6136 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6137 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
6140 /* Structure describing the image type `jpeg'. */
6142 static struct image_type jpeg_type
=
6151 /* Return non-zero if OBJECT is a valid JPEG image specification. */
6154 jpeg_image_p (object
)
6157 struct image_keyword fmt
[JPEG_LAST
];
6159 bcopy (jpeg_format
, fmt
, sizeof fmt
);
6161 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
6164 /* Must specify either the :data or :file keyword. */
6165 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
6168 #endif /* HAVE_JPEG || HAVE_NS */
6172 /* Work around a warning about HAVE_STDLIB_H being redefined in
6174 #ifdef HAVE_STDLIB_H
6175 #define HAVE_STDLIB_H_1
6176 #undef HAVE_STDLIB_H
6177 #endif /* HAVE_STLIB_H */
6179 #if defined (HAVE_NTGUI) && !defined (__WIN32__)
6180 /* In older releases of the jpeg library, jpeglib.h will define boolean
6181 differently depending on __WIN32__, so make sure it is defined. */
6185 #include <jpeglib.h>
6188 #ifdef HAVE_STLIB_H_1
6189 #define HAVE_STDLIB_H 1
6194 /* JPEG library details. */
6195 DEF_IMGLIB_FN (jpeg_CreateDecompress
);
6196 DEF_IMGLIB_FN (jpeg_start_decompress
);
6197 DEF_IMGLIB_FN (jpeg_finish_decompress
);
6198 DEF_IMGLIB_FN (jpeg_destroy_decompress
);
6199 DEF_IMGLIB_FN (jpeg_read_header
);
6200 DEF_IMGLIB_FN (jpeg_read_scanlines
);
6201 DEF_IMGLIB_FN (jpeg_std_error
);
6202 DEF_IMGLIB_FN (jpeg_resync_to_restart
);
6205 init_jpeg_functions (Lisp_Object libraries
)
6209 if (!(library
= w32_delayed_load (libraries
, Qjpeg
)))
6212 LOAD_IMGLIB_FN (library
, jpeg_finish_decompress
);
6213 LOAD_IMGLIB_FN (library
, jpeg_read_scanlines
);
6214 LOAD_IMGLIB_FN (library
, jpeg_start_decompress
);
6215 LOAD_IMGLIB_FN (library
, jpeg_read_header
);
6216 LOAD_IMGLIB_FN (library
, jpeg_CreateDecompress
);
6217 LOAD_IMGLIB_FN (library
, jpeg_destroy_decompress
);
6218 LOAD_IMGLIB_FN (library
, jpeg_std_error
);
6219 LOAD_IMGLIB_FN (library
, jpeg_resync_to_restart
);
6223 /* Wrapper since we can't directly assign the function pointer
6224 to another function pointer that was declared more completely easily. */
6226 jpeg_resync_to_restart_wrapper (cinfo
, desired
)
6227 j_decompress_ptr cinfo
;
6230 return fn_jpeg_resync_to_restart (cinfo
, desired
);
6235 #define fn_jpeg_CreateDecompress(a,b,c) jpeg_create_decompress(a)
6236 #define fn_jpeg_start_decompress jpeg_start_decompress
6237 #define fn_jpeg_finish_decompress jpeg_finish_decompress
6238 #define fn_jpeg_destroy_decompress jpeg_destroy_decompress
6239 #define fn_jpeg_read_header jpeg_read_header
6240 #define fn_jpeg_read_scanlines jpeg_read_scanlines
6241 #define fn_jpeg_std_error jpeg_std_error
6242 #define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart
6244 #endif /* HAVE_NTGUI */
6246 struct my_jpeg_error_mgr
6248 struct jpeg_error_mgr pub
;
6249 jmp_buf setjmp_buffer
;
6254 my_error_exit (cinfo
)
6257 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
6258 longjmp (mgr
->setjmp_buffer
, 1);
6262 /* Init source method for JPEG data source manager. Called by
6263 jpeg_read_header() before any data is actually read. See
6264 libjpeg.doc from the JPEG lib distribution. */
6267 our_common_init_source (cinfo
)
6268 j_decompress_ptr cinfo
;
6273 /* Method to terminate data source. Called by
6274 jpeg_finish_decompress() after all data has been processed. */
6277 our_common_term_source (cinfo
)
6278 j_decompress_ptr cinfo
;
6283 /* Fill input buffer method for JPEG data source manager. Called
6284 whenever more data is needed. We read the whole image in one step,
6285 so this only adds a fake end of input marker at the end. */
6287 static JOCTET our_memory_buffer
[2];
6290 our_memory_fill_input_buffer (cinfo
)
6291 j_decompress_ptr cinfo
;
6293 /* Insert a fake EOI marker. */
6294 struct jpeg_source_mgr
*src
= cinfo
->src
;
6296 our_memory_buffer
[0] = (JOCTET
) 0xFF;
6297 our_memory_buffer
[1] = (JOCTET
) JPEG_EOI
;
6299 src
->next_input_byte
= our_memory_buffer
;
6300 src
->bytes_in_buffer
= 2;
6305 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6306 is the JPEG data source manager. */
6309 our_memory_skip_input_data (cinfo
, num_bytes
)
6310 j_decompress_ptr cinfo
;
6313 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6317 if (num_bytes
> src
->bytes_in_buffer
)
6318 ERREXIT (cinfo
, JERR_INPUT_EOF
);
6320 src
->bytes_in_buffer
-= num_bytes
;
6321 src
->next_input_byte
+= num_bytes
;
6326 /* Set up the JPEG lib for reading an image from DATA which contains
6327 LEN bytes. CINFO is the decompression info structure created for
6328 reading the image. */
6331 jpeg_memory_src (cinfo
, data
, len
)
6332 j_decompress_ptr cinfo
;
6336 struct jpeg_source_mgr
*src
;
6338 if (cinfo
->src
== NULL
)
6340 /* First time for this JPEG object? */
6341 cinfo
->src
= (struct jpeg_source_mgr
*)
6342 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6343 sizeof (struct jpeg_source_mgr
));
6344 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6345 src
->next_input_byte
= data
;
6348 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6349 src
->init_source
= our_common_init_source
;
6350 src
->fill_input_buffer
= our_memory_fill_input_buffer
;
6351 src
->skip_input_data
= our_memory_skip_input_data
;
6352 src
->resync_to_restart
= jpeg_resync_to_restart_wrapper
; /* Use default method. */
6353 src
->term_source
= our_common_term_source
;
6354 src
->bytes_in_buffer
= len
;
6355 src
->next_input_byte
= data
;
6359 struct jpeg_stdio_mgr
6361 struct jpeg_source_mgr mgr
;
6368 /* Size of buffer to read JPEG from file.
6369 Not too big, as we want to use alloc_small. */
6370 #define JPEG_STDIO_BUFFER_SIZE 8192
6373 /* Fill input buffer method for JPEG data source manager. Called
6374 whenever more data is needed. The data is read from a FILE *. */
6377 our_stdio_fill_input_buffer (cinfo
)
6378 j_decompress_ptr cinfo
;
6380 struct jpeg_stdio_mgr
*src
;
6382 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6387 bytes
= fread (src
->buffer
, 1, JPEG_STDIO_BUFFER_SIZE
, src
->file
);
6389 src
->mgr
.bytes_in_buffer
= bytes
;
6392 WARNMS (cinfo
, JWRN_JPEG_EOF
);
6394 src
->buffer
[0] = (JOCTET
) 0xFF;
6395 src
->buffer
[1] = (JOCTET
) JPEG_EOI
;
6396 src
->mgr
.bytes_in_buffer
= 2;
6398 src
->mgr
.next_input_byte
= src
->buffer
;
6405 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6406 is the JPEG data source manager. */
6409 our_stdio_skip_input_data (cinfo
, num_bytes
)
6410 j_decompress_ptr cinfo
;
6413 struct jpeg_stdio_mgr
*src
;
6414 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6416 while (num_bytes
> 0 && !src
->finished
)
6418 if (num_bytes
<= src
->mgr
.bytes_in_buffer
)
6420 src
->mgr
.bytes_in_buffer
-= num_bytes
;
6421 src
->mgr
.next_input_byte
+= num_bytes
;
6426 num_bytes
-= src
->mgr
.bytes_in_buffer
;
6427 src
->mgr
.bytes_in_buffer
= 0;
6428 src
->mgr
.next_input_byte
= NULL
;
6430 our_stdio_fill_input_buffer (cinfo
);
6436 /* Set up the JPEG lib for reading an image from a FILE *.
6437 CINFO is the decompression info structure created for
6438 reading the image. */
6441 jpeg_file_src (cinfo
, fp
)
6442 j_decompress_ptr cinfo
;
6445 struct jpeg_stdio_mgr
*src
;
6447 if (cinfo
->src
!= NULL
)
6448 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6451 /* First time for this JPEG object? */
6452 cinfo
->src
= (struct jpeg_source_mgr
*)
6453 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6454 sizeof (struct jpeg_stdio_mgr
));
6455 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6456 src
->buffer
= (JOCTET
*)
6457 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6458 JPEG_STDIO_BUFFER_SIZE
);
6463 src
->mgr
.init_source
= our_common_init_source
;
6464 src
->mgr
.fill_input_buffer
= our_stdio_fill_input_buffer
;
6465 src
->mgr
.skip_input_data
= our_stdio_skip_input_data
;
6466 src
->mgr
.resync_to_restart
= jpeg_resync_to_restart_wrapper
; /* Use default method. */
6467 src
->mgr
.term_source
= our_common_term_source
;
6468 src
->mgr
.bytes_in_buffer
= 0;
6469 src
->mgr
.next_input_byte
= NULL
;
6473 /* Load image IMG for use on frame F. Patterned after example.c
6474 from the JPEG lib. */
6481 struct jpeg_decompress_struct cinfo
;
6482 struct my_jpeg_error_mgr mgr
;
6483 Lisp_Object file
, specified_file
;
6484 Lisp_Object specified_data
;
6485 FILE * volatile fp
= NULL
;
6487 int row_stride
, x
, y
;
6488 XImagePtr ximg
= NULL
;
6490 unsigned long *colors
;
6492 struct gcpro gcpro1
;
6494 /* Open the JPEG file. */
6495 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6496 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6500 if (NILP (specified_data
))
6502 file
= x_find_image_file (specified_file
);
6503 if (!STRINGP (file
))
6505 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6510 fp
= fopen (SDATA (file
), "rb");
6513 image_error ("Cannot open `%s'", file
, Qnil
);
6519 /* Customize libjpeg's error handling to call my_error_exit when an
6520 error is detected. This function will perform a longjmp.
6521 Casting return value avoids a GCC warning on W32. */
6522 cinfo
.err
= (struct jpeg_error_mgr
*)fn_jpeg_std_error (&mgr
.pub
);
6523 mgr
.pub
.error_exit
= my_error_exit
;
6525 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
6529 /* Called from my_error_exit. Display a JPEG error. */
6530 char buffer
[JMSG_LENGTH_MAX
];
6531 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
6532 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
6533 build_string (buffer
));
6536 /* Close the input file and destroy the JPEG object. */
6538 fclose ((FILE *) fp
);
6539 fn_jpeg_destroy_decompress (&cinfo
);
6541 /* If we already have an XImage, free that. */
6542 x_destroy_x_image (ximg
);
6544 /* Free pixmap and colors. */
6545 x_clear_image (f
, img
);
6551 /* Create the JPEG decompression object. Let it read from fp.
6552 Read the JPEG image header. */
6553 fn_jpeg_CreateDecompress (&cinfo
, JPEG_LIB_VERSION
, sizeof (cinfo
));
6555 if (NILP (specified_data
))
6556 jpeg_file_src (&cinfo
, (FILE *) fp
);
6558 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
6559 SBYTES (specified_data
));
6561 fn_jpeg_read_header (&cinfo
, 1);
6563 /* Customize decompression so that color quantization will be used.
6564 Start decompression. */
6565 cinfo
.quantize_colors
= 1;
6566 fn_jpeg_start_decompress (&cinfo
);
6567 width
= img
->width
= cinfo
.output_width
;
6568 height
= img
->height
= cinfo
.output_height
;
6570 if (!check_image_size (f
, width
, height
))
6572 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
6573 longjmp (mgr
.setjmp_buffer
, 2);
6576 /* Create X image and pixmap. */
6577 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
6578 longjmp (mgr
.setjmp_buffer
, 2);
6580 /* Allocate colors. When color quantization is used,
6581 cinfo.actual_number_of_colors has been set with the number of
6582 colors generated, and cinfo.colormap is a two-dimensional array
6583 of color indices in the range 0..cinfo.actual_number_of_colors.
6584 No more than 255 colors will be generated. */
6588 if (cinfo
.out_color_components
> 2)
6589 ir
= 0, ig
= 1, ib
= 2;
6590 else if (cinfo
.out_color_components
> 1)
6591 ir
= 0, ig
= 1, ib
= 0;
6593 ir
= 0, ig
= 0, ib
= 0;
6595 /* Use the color table mechanism because it handles colors that
6596 cannot be allocated nicely. Such colors will be replaced with
6597 a default color, and we don't have to care about which colors
6598 can be freed safely, and which can't. */
6599 init_color_table ();
6600 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
6603 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
6605 /* Multiply RGB values with 255 because X expects RGB values
6606 in the range 0..0xffff. */
6607 int r
= cinfo
.colormap
[ir
][i
] << 8;
6608 int g
= cinfo
.colormap
[ig
][i
] << 8;
6609 int b
= cinfo
.colormap
[ib
][i
] << 8;
6610 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
6613 #ifdef COLOR_TABLE_SUPPORT
6614 /* Remember those colors actually allocated. */
6615 img
->colors
= colors_in_color_table (&img
->ncolors
);
6616 free_color_table ();
6617 #endif /* COLOR_TABLE_SUPPORT */
6621 row_stride
= width
* cinfo
.output_components
;
6622 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
6624 for (y
= 0; y
< height
; ++y
)
6626 fn_jpeg_read_scanlines (&cinfo
, buffer
, 1);
6627 for (x
= 0; x
< cinfo
.output_width
; ++x
)
6628 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
6632 fn_jpeg_finish_decompress (&cinfo
);
6633 fn_jpeg_destroy_decompress (&cinfo
);
6635 fclose ((FILE *) fp
);
6637 /* Maybe fill in the background field while we have ximg handy. */
6638 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6639 /* Casting avoids a GCC warning. */
6640 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6642 /* Put the image into the pixmap. */
6643 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6644 x_destroy_x_image (ximg
);
6649 #else /* HAVE_JPEG */
6653 jpeg_load (struct frame
*f
, struct image
*img
)
6655 return ns_load_image(f
, img
,
6656 image_spec_value (img
->spec
, QCfile
, NULL
),
6657 image_spec_value (img
->spec
, QCdata
, NULL
));
6659 #endif /* HAVE_NS */
6661 #endif /* !HAVE_JPEG */
6665 /***********************************************************************
6667 ***********************************************************************/
6669 #if defined (HAVE_TIFF) || defined (HAVE_NS)
6671 static int tiff_image_p
P_ ((Lisp_Object object
));
6672 static int tiff_load
P_ ((struct frame
*f
, struct image
*img
));
6674 /* The symbol `tiff' identifying images of this type. */
6678 /* Indices of image specification fields in tiff_format, below. */
6680 enum tiff_keyword_index
6689 TIFF_HEURISTIC_MASK
,
6696 /* Vector of image_keyword structures describing the format
6697 of valid user-defined image specifications. */
6699 static const struct image_keyword tiff_format
[TIFF_LAST
] =
6701 {":type", IMAGE_SYMBOL_VALUE
, 1},
6702 {":data", IMAGE_STRING_VALUE
, 0},
6703 {":file", IMAGE_STRING_VALUE
, 0},
6704 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6705 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6706 {":relief", IMAGE_INTEGER_VALUE
, 0},
6707 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6708 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6709 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6710 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
6711 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0}
6714 /* Structure describing the image type `tiff'. */
6716 static struct image_type tiff_type
=
6725 /* Return non-zero if OBJECT is a valid TIFF image specification. */
6728 tiff_image_p (object
)
6731 struct image_keyword fmt
[TIFF_LAST
];
6732 bcopy (tiff_format
, fmt
, sizeof fmt
);
6734 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
6737 /* Must specify either the :data or :file keyword. */
6738 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
6741 #endif /* HAVE_TIFF || HAVE_NS */
6749 /* TIFF library details. */
6750 DEF_IMGLIB_FN (TIFFSetErrorHandler
);
6751 DEF_IMGLIB_FN (TIFFSetWarningHandler
);
6752 DEF_IMGLIB_FN (TIFFOpen
);
6753 DEF_IMGLIB_FN (TIFFClientOpen
);
6754 DEF_IMGLIB_FN (TIFFGetField
);
6755 DEF_IMGLIB_FN (TIFFReadRGBAImage
);
6756 DEF_IMGLIB_FN (TIFFClose
);
6757 DEF_IMGLIB_FN (TIFFSetDirectory
);
6760 init_tiff_functions (Lisp_Object libraries
)
6764 if (!(library
= w32_delayed_load (libraries
, Qtiff
)))
6767 LOAD_IMGLIB_FN (library
, TIFFSetErrorHandler
);
6768 LOAD_IMGLIB_FN (library
, TIFFSetWarningHandler
);
6769 LOAD_IMGLIB_FN (library
, TIFFOpen
);
6770 LOAD_IMGLIB_FN (library
, TIFFClientOpen
);
6771 LOAD_IMGLIB_FN (library
, TIFFGetField
);
6772 LOAD_IMGLIB_FN (library
, TIFFReadRGBAImage
);
6773 LOAD_IMGLIB_FN (library
, TIFFClose
);
6774 LOAD_IMGLIB_FN (library
, TIFFSetDirectory
);
6780 #define fn_TIFFSetErrorHandler TIFFSetErrorHandler
6781 #define fn_TIFFSetWarningHandler TIFFSetWarningHandler
6782 #define fn_TIFFOpen TIFFOpen
6783 #define fn_TIFFClientOpen TIFFClientOpen
6784 #define fn_TIFFGetField TIFFGetField
6785 #define fn_TIFFReadRGBAImage TIFFReadRGBAImage
6786 #define fn_TIFFClose TIFFClose
6787 #define fn_TIFFSetDirectory TIFFSetDirectory
6788 #endif /* HAVE_NTGUI */
6791 /* Reading from a memory buffer for TIFF images Based on the PNG
6792 memory source, but we have to provide a lot of extra functions.
6795 We really only need to implement read and seek, but I am not
6796 convinced that the TIFF library is smart enough not to destroy
6797 itself if we only hand it the function pointers we need to
6802 unsigned char *bytes
;
6809 tiff_read_from_memory (data
, buf
, size
)
6814 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6816 if (size
> src
->len
- src
->index
)
6818 bcopy (src
->bytes
+ src
->index
, buf
, size
);
6824 tiff_write_from_memory (data
, buf
, size
)
6833 tiff_seek_in_memory (data
, off
, whence
)
6838 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6843 case SEEK_SET
: /* Go from beginning of source. */
6847 case SEEK_END
: /* Go from end of source. */
6848 idx
= src
->len
+ off
;
6851 case SEEK_CUR
: /* Go from current position. */
6852 idx
= src
->index
+ off
;
6855 default: /* Invalid `whence'. */
6859 if (idx
> src
->len
|| idx
< 0)
6867 tiff_close_memory (data
)
6875 tiff_mmap_memory (data
, pbase
, psize
)
6880 /* It is already _IN_ memory. */
6885 tiff_unmap_memory (data
, base
, size
)
6890 /* We don't need to do this. */
6894 tiff_size_of_memory (data
)
6897 return ((tiff_memory_source
*) data
)->len
;
6902 tiff_error_handler (title
, format
, ap
)
6903 const char *title
, *format
;
6909 len
= sprintf (buf
, "TIFF error: %s ", title
);
6910 vsprintf (buf
+ len
, format
, ap
);
6911 add_to_log (buf
, Qnil
, Qnil
);
6916 tiff_warning_handler (title
, format
, ap
)
6917 const char *title
, *format
;
6923 len
= sprintf (buf
, "TIFF warning: %s ", title
);
6924 vsprintf (buf
+ len
, format
, ap
);
6925 add_to_log (buf
, Qnil
, Qnil
);
6929 /* Load TIFF image IMG for use on frame F. Value is non-zero if
6937 Lisp_Object file
, specified_file
;
6938 Lisp_Object specified_data
;
6940 int width
, height
, x
, y
, count
;
6944 struct gcpro gcpro1
;
6945 tiff_memory_source memsrc
;
6948 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6949 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6953 fn_TIFFSetErrorHandler (tiff_error_handler
);
6954 fn_TIFFSetWarningHandler (tiff_warning_handler
);
6956 if (NILP (specified_data
))
6958 /* Read from a file */
6959 file
= x_find_image_file (specified_file
);
6960 if (!STRINGP (file
))
6962 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6967 /* Try to open the image file. Casting return value avoids a
6968 GCC warning on W32. */
6969 tiff
= (TIFF
*)fn_TIFFOpen (SDATA (file
), "r");
6972 image_error ("Cannot open `%s'", file
, Qnil
);
6979 /* Memory source! */
6980 memsrc
.bytes
= SDATA (specified_data
);
6981 memsrc
.len
= SBYTES (specified_data
);
6984 /* Casting return value avoids a GCC warning on W32. */
6985 tiff
= (TIFF
*)fn_TIFFClientOpen ("memory_source", "r", &memsrc
,
6986 (TIFFReadWriteProc
) tiff_read_from_memory
,
6987 (TIFFReadWriteProc
) tiff_write_from_memory
,
6988 tiff_seek_in_memory
,
6990 tiff_size_of_memory
,
6996 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
7002 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
7003 if (INTEGERP (image
))
7005 int ino
= XFASTINT (image
);
7006 if (!fn_TIFFSetDirectory (tiff
, ino
))
7008 image_error ("Invalid image number `%s' in image `%s'",
7010 fn_TIFFClose (tiff
);
7016 /* Get width and height of the image, and allocate a raster buffer
7017 of width x height 32-bit values. */
7018 fn_TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
7019 fn_TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
7021 if (!check_image_size (f
, width
, height
))
7023 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7024 fn_TIFFClose (tiff
);
7029 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
7031 rc
= fn_TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
7033 /* Count the number of images in the file. */
7034 for (count
= 1, rc2
= 1; rc2
; count
++)
7035 rc2
= fn_TIFFSetDirectory (tiff
, count
);
7038 img
->data
.lisp_val
= Fcons (Qcount
,
7039 Fcons (make_number (count
),
7040 img
->data
.lisp_val
));
7042 fn_TIFFClose (tiff
);
7045 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
7051 /* Create the X image and pixmap. */
7052 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
7059 /* Initialize the color table. */
7060 init_color_table ();
7062 /* Process the pixel raster. Origin is in the lower-left corner. */
7063 for (y
= 0; y
< height
; ++y
)
7065 uint32
*row
= buf
+ y
* width
;
7067 for (x
= 0; x
< width
; ++x
)
7069 uint32 abgr
= row
[x
];
7070 int r
= TIFFGetR (abgr
) << 8;
7071 int g
= TIFFGetG (abgr
) << 8;
7072 int b
= TIFFGetB (abgr
) << 8;
7073 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
7077 #ifdef COLOR_TABLE_SUPPORT
7078 /* Remember the colors allocated for the image. Free the color table. */
7079 img
->colors
= colors_in_color_table (&img
->ncolors
);
7080 free_color_table ();
7081 #endif /* COLOR_TABLE_SUPPORT */
7084 img
->height
= height
;
7086 /* Maybe fill in the background field while we have ximg handy. */
7087 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7088 /* Casting avoids a GCC warning on W32. */
7089 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
7091 /* Put the image into the pixmap, then free the X image and its buffer. */
7092 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7093 x_destroy_x_image (ximg
);
7100 #else /* HAVE_TIFF */
7104 tiff_load (struct frame
*f
, struct image
*img
)
7106 return ns_load_image(f
, img
,
7107 image_spec_value (img
->spec
, QCfile
, NULL
),
7108 image_spec_value (img
->spec
, QCdata
, NULL
));
7110 #endif /* HAVE_NS */
7112 #endif /* !HAVE_TIFF */
7116 /***********************************************************************
7118 ***********************************************************************/
7120 #if defined (HAVE_GIF) || defined (HAVE_NS)
7122 static int gif_image_p
P_ ((Lisp_Object object
));
7123 static int gif_load
P_ ((struct frame
*f
, struct image
*img
));
7124 static void gif_clear_image
P_ ((struct frame
*f
, struct image
*img
));
7126 /* The symbol `gif' identifying images of this type. */
7130 /* Indices of image specification fields in gif_format, below. */
7132 enum gif_keyword_index
7148 /* Vector of image_keyword structures describing the format
7149 of valid user-defined image specifications. */
7151 static const struct image_keyword gif_format
[GIF_LAST
] =
7153 {":type", IMAGE_SYMBOL_VALUE
, 1},
7154 {":data", IMAGE_STRING_VALUE
, 0},
7155 {":file", IMAGE_STRING_VALUE
, 0},
7156 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7157 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7158 {":relief", IMAGE_INTEGER_VALUE
, 0},
7159 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7160 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7161 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7162 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7163 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7166 /* Structure describing the image type `gif'. */
7168 static struct image_type gif_type
=
7177 /* Free X resources of GIF image IMG which is used on frame F. */
7180 gif_clear_image (f
, img
)
7184 /* IMG->data.ptr_val may contain extension data. */
7185 img
->data
.lisp_val
= Qnil
;
7186 x_clear_image (f
, img
);
7189 /* Return non-zero if OBJECT is a valid GIF image specification. */
7192 gif_image_p (object
)
7195 struct image_keyword fmt
[GIF_LAST
];
7196 bcopy (gif_format
, fmt
, sizeof fmt
);
7198 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
7201 /* Must specify either the :data or :file keyword. */
7202 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
7205 #endif /* HAVE_GIF */
7209 #if defined (HAVE_NTGUI)
7210 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
7211 Undefine before redefining to avoid a preprocessor warning. */
7215 /* avoid conflict with QuickdrawText.h */
7216 #define DrawText gif_DrawText
7217 #include <gif_lib.h>
7220 #else /* HAVE_NTGUI */
7222 #include <gif_lib.h>
7224 #endif /* HAVE_NTGUI */
7229 /* GIF library details. */
7230 DEF_IMGLIB_FN (DGifCloseFile
);
7231 DEF_IMGLIB_FN (DGifSlurp
);
7232 DEF_IMGLIB_FN (DGifOpen
);
7233 DEF_IMGLIB_FN (DGifOpenFileName
);
7236 init_gif_functions (Lisp_Object libraries
)
7240 if (!(library
= w32_delayed_load (libraries
, Qgif
)))
7243 LOAD_IMGLIB_FN (library
, DGifCloseFile
);
7244 LOAD_IMGLIB_FN (library
, DGifSlurp
);
7245 LOAD_IMGLIB_FN (library
, DGifOpen
);
7246 LOAD_IMGLIB_FN (library
, DGifOpenFileName
);
7252 #define fn_DGifCloseFile DGifCloseFile
7253 #define fn_DGifSlurp DGifSlurp
7254 #define fn_DGifOpen DGifOpen
7255 #define fn_DGifOpenFileName DGifOpenFileName
7257 #endif /* HAVE_NTGUI */
7259 /* Reading a GIF image from memory
7260 Based on the PNG memory stuff to a certain extent. */
7264 unsigned char *bytes
;
7270 /* Make the current memory source available to gif_read_from_memory.
7271 It's done this way because not all versions of libungif support
7272 a UserData field in the GifFileType structure. */
7273 static gif_memory_source
*current_gif_memory_src
;
7276 gif_read_from_memory (file
, buf
, len
)
7281 gif_memory_source
*src
= current_gif_memory_src
;
7283 if (len
> src
->len
- src
->index
)
7286 bcopy (src
->bytes
+ src
->index
, buf
, len
);
7292 /* Load GIF image IMG for use on frame F. Value is non-zero if
7295 static const int interlace_start
[] = {0, 4, 2, 1};
7296 static const int interlace_increment
[] = {8, 8, 4, 2};
7303 Lisp_Object file
, specified_file
;
7304 Lisp_Object specified_data
;
7305 int rc
, width
, height
, x
, y
, i
;
7307 ColorMapObject
*gif_color_map
;
7308 unsigned long pixel_colors
[256];
7310 struct gcpro gcpro1
;
7312 int ino
, image_height
, image_width
;
7313 gif_memory_source memsrc
;
7314 unsigned char *raster
;
7316 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7317 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7321 if (NILP (specified_data
))
7323 file
= x_find_image_file (specified_file
);
7324 if (!STRINGP (file
))
7326 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7331 /* Open the GIF file. Casting return value avoids a GCC warning
7333 gif
= (GifFileType
*)fn_DGifOpenFileName (SDATA (file
));
7336 image_error ("Cannot open `%s'", file
, Qnil
);
7343 /* Read from memory! */
7344 current_gif_memory_src
= &memsrc
;
7345 memsrc
.bytes
= SDATA (specified_data
);
7346 memsrc
.len
= SBYTES (specified_data
);
7349 /* Casting return value avoids a GCC warning on W32. */
7350 gif
= (GifFileType
*) fn_DGifOpen (&memsrc
, gif_read_from_memory
);
7353 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
7359 /* Before reading entire contents, check the declared image size. */
7360 if (!check_image_size (f
, gif
->SWidth
, gif
->SHeight
))
7362 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7363 fn_DGifCloseFile (gif
);
7368 /* Read entire contents. */
7369 rc
= fn_DGifSlurp (gif
);
7370 if (rc
== GIF_ERROR
)
7372 image_error ("Error reading `%s'", img
->spec
, Qnil
);
7373 fn_DGifCloseFile (gif
);
7378 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
7379 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
7380 if (ino
>= gif
->ImageCount
)
7382 image_error ("Invalid image number `%s' in image `%s'",
7384 fn_DGifCloseFile (gif
);
7389 img
->corners
[TOP_CORNER
] = gif
->SavedImages
[ino
].ImageDesc
.Top
;
7390 img
->corners
[LEFT_CORNER
] = gif
->SavedImages
[ino
].ImageDesc
.Left
;
7391 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
7392 img
->corners
[BOT_CORNER
] = img
->corners
[TOP_CORNER
] + image_height
;
7393 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
7394 img
->corners
[RIGHT_CORNER
] = img
->corners
[LEFT_CORNER
] + image_width
;
7396 width
= img
->width
= max (gif
->SWidth
,
7397 max (gif
->Image
.Left
+ gif
->Image
.Width
,
7398 img
->corners
[RIGHT_CORNER
]));
7399 height
= img
->height
= max (gif
->SHeight
,
7400 max (gif
->Image
.Top
+ gif
->Image
.Height
,
7401 img
->corners
[BOT_CORNER
]));
7403 if (!check_image_size (f
, width
, height
))
7405 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7406 fn_DGifCloseFile (gif
);
7411 /* Create the X image and pixmap. */
7412 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
7414 fn_DGifCloseFile (gif
);
7419 /* Allocate colors. */
7420 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
7422 gif_color_map
= gif
->SColorMap
;
7423 init_color_table ();
7424 bzero (pixel_colors
, sizeof pixel_colors
);
7427 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
7429 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
7430 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
7431 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
7432 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
7435 #ifdef COLOR_TABLE_SUPPORT
7436 img
->colors
= colors_in_color_table (&img
->ncolors
);
7437 free_color_table ();
7438 #endif /* COLOR_TABLE_SUPPORT */
7440 /* Clear the part of the screen image that are not covered by
7441 the image from the GIF file. Full animated GIF support
7442 requires more than can be done here (see the gif89 spec,
7443 disposal methods). Let's simply assume that the part
7444 not covered by a sub-image is in the frame's background color. */
7445 for (y
= 0; y
< img
->corners
[TOP_CORNER
]; ++y
)
7446 for (x
= 0; x
< width
; ++x
)
7447 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7449 for (y
= img
->corners
[BOT_CORNER
]; y
< height
; ++y
)
7450 for (x
= 0; x
< width
; ++x
)
7451 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7453 for (y
= img
->corners
[TOP_CORNER
]; y
< img
->corners
[BOT_CORNER
]; ++y
)
7455 for (x
= 0; x
< img
->corners
[LEFT_CORNER
]; ++x
)
7456 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7457 for (x
= img
->corners
[RIGHT_CORNER
]; x
< width
; ++x
)
7458 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7461 /* Read the GIF image into the X image. We use a local variable
7462 `raster' here because RasterBits below is a char *, and invites
7463 problems with bytes >= 0x80. */
7464 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
7466 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
7469 int row
= interlace_start
[0];
7473 for (y
= 0; y
< image_height
; y
++)
7475 if (row
>= image_height
)
7477 row
= interlace_start
[++pass
];
7478 while (row
>= image_height
)
7479 row
= interlace_start
[++pass
];
7482 for (x
= 0; x
< image_width
; x
++)
7484 int i
= raster
[(y
* image_width
) + x
];
7485 XPutPixel (ximg
, x
+ img
->corners
[LEFT_CORNER
],
7486 row
+ img
->corners
[TOP_CORNER
], pixel_colors
[i
]);
7489 row
+= interlace_increment
[pass
];
7494 for (y
= 0; y
< image_height
; ++y
)
7495 for (x
= 0; x
< image_width
; ++x
)
7497 int i
= raster
[y
* image_width
+ x
];
7498 XPutPixel (ximg
, x
+ img
->corners
[LEFT_CORNER
],
7499 y
+ img
->corners
[TOP_CORNER
], pixel_colors
[i
]);
7503 /* Save GIF image extension data for `image-extension-data'.
7504 Format is (count IMAGES FUNCTION "BYTES" ...). */
7505 img
->data
.lisp_val
= Qnil
;
7506 if (gif
->SavedImages
[ino
].ExtensionBlockCount
> 0)
7508 ExtensionBlock
*ext
= gif
->SavedImages
[ino
].ExtensionBlocks
;
7509 for (i
= 0; i
< gif
->SavedImages
[ino
].ExtensionBlockCount
; i
++, ext
++)
7510 /* Append (... FUNCTION "BYTES") */
7511 img
->data
.lisp_val
= Fcons (make_unibyte_string (ext
->Bytes
, ext
->ByteCount
),
7512 Fcons (make_number (ext
->Function
),
7513 img
->data
.lisp_val
));
7514 img
->data
.lisp_val
= Fnreverse (img
->data
.lisp_val
);
7516 if (gif
->ImageCount
> 1)
7517 img
->data
.lisp_val
= Fcons (Qcount
,
7518 Fcons (make_number (gif
->ImageCount
),
7519 img
->data
.lisp_val
));
7521 fn_DGifCloseFile (gif
);
7523 /* Maybe fill in the background field while we have ximg handy. */
7524 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7525 /* Casting avoids a GCC warning. */
7526 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
7528 /* Put the image into the pixmap, then free the X image and its buffer. */
7529 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7530 x_destroy_x_image (ximg
);
7536 #else /* !HAVE_GIF */
7540 gif_load (struct frame
*f
, struct image
*img
)
7542 return ns_load_image(f
, img
,
7543 image_spec_value (img
->spec
, QCfile
, NULL
),
7544 image_spec_value (img
->spec
, QCdata
, NULL
));
7546 #endif /* HAVE_NS */
7548 #endif /* HAVE_GIF */
7552 /***********************************************************************
7554 ***********************************************************************/
7556 #if defined (HAVE_RSVG)
7558 /* Function prototypes. */
7560 static int svg_image_p
P_ ((Lisp_Object object
));
7561 static int svg_load
P_ ((struct frame
*f
, struct image
*img
));
7563 static int svg_load_image
P_ ((struct frame
*, struct image
*,
7564 unsigned char *, unsigned int));
7566 /* The symbol `svg' identifying images of this type. */
7570 /* Indices of image specification fields in svg_format, below. */
7572 enum svg_keyword_index
7587 /* Vector of image_keyword structures describing the format
7588 of valid user-defined image specifications. */
7590 static const struct image_keyword svg_format
[SVG_LAST
] =
7592 {":type", IMAGE_SYMBOL_VALUE
, 1},
7593 {":data", IMAGE_STRING_VALUE
, 0},
7594 {":file", IMAGE_STRING_VALUE
, 0},
7595 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7596 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7597 {":relief", IMAGE_INTEGER_VALUE
, 0},
7598 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7599 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7600 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7601 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7604 /* Structure describing the image type `svg'. Its the same type of
7605 structure defined for all image formats, handled by emacs image
7606 functions. See struct image_type in dispextern.h. */
7608 static struct image_type svg_type
=
7610 /* An identifier showing that this is an image structure for the SVG format. */
7612 /* Handle to a function that can be used to identify a SVG file. */
7614 /* Handle to function used to load a SVG file. */
7616 /* Handle to function to free sresources for SVG. */
7618 /* An internal field to link to the next image type in a list of
7619 image types, will be filled in when registering the format. */
7624 /* Return non-zero if OBJECT is a valid SVG image specification. Do
7625 this by calling parse_image_spec and supplying the keywords that
7626 identify the SVG format. */
7629 svg_image_p (object
)
7632 struct image_keyword fmt
[SVG_LAST
];
7633 bcopy (svg_format
, fmt
, sizeof fmt
);
7635 if (!parse_image_spec (object
, fmt
, SVG_LAST
, Qsvg
))
7638 /* Must specify either the :data or :file keyword. */
7639 return fmt
[SVG_FILE
].count
+ fmt
[SVG_DATA
].count
== 1;
7642 #include <librsvg/rsvg.h>
7646 /* SVG library functions. */
7647 DEF_IMGLIB_FN (rsvg_handle_new
);
7648 DEF_IMGLIB_FN (rsvg_handle_get_dimensions
);
7649 DEF_IMGLIB_FN (rsvg_handle_write
);
7650 DEF_IMGLIB_FN (rsvg_handle_close
);
7651 DEF_IMGLIB_FN (rsvg_handle_get_pixbuf
);
7652 DEF_IMGLIB_FN (rsvg_handle_free
);
7654 DEF_IMGLIB_FN (gdk_pixbuf_get_width
);
7655 DEF_IMGLIB_FN (gdk_pixbuf_get_height
);
7656 DEF_IMGLIB_FN (gdk_pixbuf_get_pixels
);
7657 DEF_IMGLIB_FN (gdk_pixbuf_get_rowstride
);
7658 DEF_IMGLIB_FN (gdk_pixbuf_get_colorspace
);
7659 DEF_IMGLIB_FN (gdk_pixbuf_get_n_channels
);
7660 DEF_IMGLIB_FN (gdk_pixbuf_get_has_alpha
);
7661 DEF_IMGLIB_FN (gdk_pixbuf_get_bits_per_sample
);
7663 DEF_IMGLIB_FN (g_type_init
);
7664 DEF_IMGLIB_FN (g_object_unref
);
7665 DEF_IMGLIB_FN (g_error_free
);
7667 Lisp_Object Qgdk_pixbuf
, Qglib
, Qgobject
;
7670 init_svg_functions (Lisp_Object libraries
)
7672 HMODULE library
, gdklib
, glib
, gobject
;
7674 if (!(glib
= w32_delayed_load (libraries
, Qglib
))
7675 || !(gobject
= w32_delayed_load (libraries
, Qgobject
))
7676 || !(gdklib
= w32_delayed_load (libraries
, Qgdk_pixbuf
))
7677 || !(library
= w32_delayed_load (libraries
, Qsvg
)))
7680 LOAD_IMGLIB_FN (library
, rsvg_handle_new
);
7681 LOAD_IMGLIB_FN (library
, rsvg_handle_get_dimensions
);
7682 LOAD_IMGLIB_FN (library
, rsvg_handle_write
);
7683 LOAD_IMGLIB_FN (library
, rsvg_handle_close
);
7684 LOAD_IMGLIB_FN (library
, rsvg_handle_get_pixbuf
);
7685 LOAD_IMGLIB_FN (library
, rsvg_handle_free
);
7687 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_width
);
7688 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_height
);
7689 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_pixels
);
7690 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_rowstride
);
7691 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_colorspace
);
7692 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_n_channels
);
7693 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_has_alpha
);
7694 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_bits_per_sample
);
7696 LOAD_IMGLIB_FN (gobject
, g_type_init
);
7697 LOAD_IMGLIB_FN (gobject
, g_object_unref
);
7698 LOAD_IMGLIB_FN (glib
, g_error_free
);
7704 /* The following aliases for library functions allow dynamic loading
7705 to be used on some platforms. */
7706 #define fn_rsvg_handle_new rsvg_handle_new
7707 #define fn_rsvg_handle_get_dimensions rsvg_handle_get_dimensions
7708 #define fn_rsvg_handle_write rsvg_handle_write
7709 #define fn_rsvg_handle_close rsvg_handle_close
7710 #define fn_rsvg_handle_get_pixbuf rsvg_handle_get_pixbuf
7711 #define fn_rsvg_handle_free rsvg_handle_free
7713 #define fn_gdk_pixbuf_get_width gdk_pixbuf_get_width
7714 #define fn_gdk_pixbuf_get_height gdk_pixbuf_get_height
7715 #define fn_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels
7716 #define fn_gdk_pixbuf_get_rowstride gdk_pixbuf_get_rowstride
7717 #define fn_gdk_pixbuf_get_colorspace gdk_pixbuf_get_colorspace
7718 #define fn_gdk_pixbuf_get_n_channels gdk_pixbuf_get_n_channels
7719 #define fn_gdk_pixbuf_get_has_alpha gdk_pixbuf_get_has_alpha
7720 #define fn_gdk_pixbuf_get_bits_per_sample gdk_pixbuf_get_bits_per_sample
7722 #define fn_g_type_init g_type_init
7723 #define fn_g_object_unref g_object_unref
7724 #define fn_g_error_free g_error_free
7725 #endif /* !HAVE_NTGUI */
7727 /* Load SVG image IMG for use on frame F. Value is non-zero if
7728 successful. this function will go into the svg_type structure, and
7729 the prototype thus needs to be compatible with that structure. */
7737 Lisp_Object file_name
;
7739 /* If IMG->spec specifies a file name, create a non-file spec from it. */
7740 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
7741 if (STRINGP (file_name
))
7744 unsigned char *contents
;
7746 struct gcpro gcpro1
;
7748 file
= x_find_image_file (file_name
);
7750 if (!STRINGP (file
))
7752 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
7757 /* Read the entire file into memory. */
7758 contents
= slurp_file (SDATA (file
), &size
);
7759 if (contents
== NULL
)
7761 image_error ("Error loading SVG image `%s'", img
->spec
, Qnil
);
7765 /* If the file was slurped into memory properly, parse it. */
7766 success_p
= svg_load_image (f
, img
, contents
, size
);
7770 /* Else its not a file, its a lisp object. Load the image from a
7771 lisp object rather than a file. */
7776 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7777 success_p
= svg_load_image (f
, img
, SDATA (data
), SBYTES (data
));
7783 /* svg_load_image is a helper function for svg_load, which does the
7784 actual loading given contents and size, apart from frame and image
7785 structures, passed from svg_load.
7787 Uses librsvg to do most of the image processing.
7789 Returns non-zero when successful. */
7791 svg_load_image (f
, img
, contents
, size
)
7792 /* Pointer to emacs frame structure. */
7794 /* Pointer to emacs image structure. */
7796 /* String containing the SVG XML data to be parsed. */
7797 unsigned char *contents
;
7798 /* Size of data in bytes. */
7801 RsvgHandle
*rsvg_handle
;
7802 RsvgDimensionData dimension_data
;
7803 GError
*error
= NULL
;
7807 const guint8
*pixels
;
7810 Lisp_Object specified_bg
;
7815 /* g_type_init is a glib function that must be called prior to using
7816 gnome type library functions. */
7818 /* Make a handle to a new rsvg object. */
7819 rsvg_handle
= (RsvgHandle
*) fn_rsvg_handle_new ();
7821 /* Parse the contents argument and fill in the rsvg_handle. */
7822 fn_rsvg_handle_write (rsvg_handle
, contents
, size
, &error
);
7823 if (error
) goto rsvg_error
;
7825 /* The parsing is complete, rsvg_handle is ready to used, close it
7826 for further writes. */
7827 fn_rsvg_handle_close (rsvg_handle
, &error
);
7828 if (error
) goto rsvg_error
;
7830 fn_rsvg_handle_get_dimensions (rsvg_handle
, &dimension_data
);
7831 if (! check_image_size (f
, dimension_data
.width
, dimension_data
.height
))
7833 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7837 /* We can now get a valid pixel buffer from the svg file, if all
7839 pixbuf
= (GdkPixbuf
*) fn_rsvg_handle_get_pixbuf (rsvg_handle
);
7840 if (!pixbuf
) goto rsvg_error
;
7841 fn_g_object_unref (rsvg_handle
);
7843 /* Extract some meta data from the svg handle. */
7844 width
= fn_gdk_pixbuf_get_width (pixbuf
);
7845 height
= fn_gdk_pixbuf_get_height (pixbuf
);
7846 pixels
= (const guint8
*) fn_gdk_pixbuf_get_pixels (pixbuf
);
7847 rowstride
= fn_gdk_pixbuf_get_rowstride (pixbuf
);
7849 /* Validate the svg meta data. */
7850 eassert (fn_gdk_pixbuf_get_colorspace (pixbuf
) == GDK_COLORSPACE_RGB
);
7851 eassert (fn_gdk_pixbuf_get_n_channels (pixbuf
) == 4);
7852 eassert (fn_gdk_pixbuf_get_has_alpha (pixbuf
));
7853 eassert (fn_gdk_pixbuf_get_bits_per_sample (pixbuf
) == 8);
7855 /* Try to create a x pixmap to hold the svg pixmap. */
7856 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
7858 fn_g_object_unref (pixbuf
);
7862 init_color_table ();
7864 /* Handle alpha channel by combining the image with a background
7866 specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
7867 if (!STRINGP (specified_bg
)
7868 || !x_defined_color (f
, SDATA (specified_bg
), &background
, 0))
7871 background
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
7872 x_query_color (f
, &background
);
7874 ns_query_color(FRAME_BACKGROUND_COLOR (f
), &background
, 1);
7878 /* SVG pixmaps specify transparency in the last byte, so right
7879 shift 8 bits to get rid of it, since emacs doesn't support
7881 background
.red
>>= 8;
7882 background
.green
>>= 8;
7883 background
.blue
>>= 8;
7885 /* This loop handles opacity values, since Emacs assumes
7886 non-transparent images. Each pixel must be "flattened" by
7887 calculating the resulting color, given the transparency of the
7888 pixel, and the image background color. */
7889 for (y
= 0; y
< height
; ++y
)
7891 for (x
= 0; x
< width
; ++x
)
7901 opacity
= *pixels
++;
7903 red
= ((red
* opacity
)
7904 + (background
.red
* ((1 << 8) - opacity
)));
7905 green
= ((green
* opacity
)
7906 + (background
.green
* ((1 << 8) - opacity
)));
7907 blue
= ((blue
* opacity
)
7908 + (background
.blue
* ((1 << 8) - opacity
)));
7910 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, red
, green
, blue
));
7913 pixels
+= rowstride
- 4 * width
;
7916 #ifdef COLOR_TABLE_SUPPORT
7917 /* Remember colors allocated for this image. */
7918 img
->colors
= colors_in_color_table (&img
->ncolors
);
7919 free_color_table ();
7920 #endif /* COLOR_TABLE_SUPPORT */
7922 fn_g_object_unref (pixbuf
);
7925 img
->height
= height
;
7927 /* Maybe fill in the background field while we have ximg handy.
7928 Casting avoids a GCC warning. */
7929 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
7931 /* Put the image into the pixmap, then free the X image and its
7933 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7934 x_destroy_x_image (ximg
);
7939 fn_g_object_unref (rsvg_handle
);
7940 /* FIXME: Use error->message so the user knows what is the actual
7941 problem with the image. */
7942 image_error ("Error parsing SVG image `%s'", img
->spec
, Qnil
);
7943 fn_g_error_free (error
);
7947 #endif /* defined (HAVE_RSVG) */
7952 /***********************************************************************
7954 ***********************************************************************/
7956 #ifdef HAVE_X_WINDOWS
7957 #define HAVE_GHOSTSCRIPT 1
7958 #endif /* HAVE_X_WINDOWS */
7960 /* The symbol `postscript' identifying images of this type. */
7962 Lisp_Object Qpostscript
;
7964 #ifdef HAVE_GHOSTSCRIPT
7966 static int gs_image_p
P_ ((Lisp_Object object
));
7967 static int gs_load
P_ ((struct frame
*f
, struct image
*img
));
7968 static void gs_clear_image
P_ ((struct frame
*f
, struct image
*img
));
7970 /* Keyword symbols. */
7972 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
7974 /* Indices of image specification fields in gs_format, below. */
7976 enum gs_keyword_index
7994 /* Vector of image_keyword structures describing the format
7995 of valid user-defined image specifications. */
7997 static const struct image_keyword gs_format
[GS_LAST
] =
7999 {":type", IMAGE_SYMBOL_VALUE
, 1},
8000 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8001 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8002 {":file", IMAGE_STRING_VALUE
, 1},
8003 {":loader", IMAGE_FUNCTION_VALUE
, 0},
8004 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
8005 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8006 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8007 {":relief", IMAGE_INTEGER_VALUE
, 0},
8008 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8009 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8010 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8011 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8014 /* Structure describing the image type `ghostscript'. */
8016 static struct image_type gs_type
=
8026 /* Free X resources of Ghostscript image IMG which is used on frame F. */
8029 gs_clear_image (f
, img
)
8033 /* IMG->data.ptr_val may contain a recorded colormap. */
8034 xfree (img
->data
.ptr_val
);
8035 x_clear_image (f
, img
);
8039 /* Return non-zero if OBJECT is a valid Ghostscript image
8046 struct image_keyword fmt
[GS_LAST
];
8050 bcopy (gs_format
, fmt
, sizeof fmt
);
8052 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
8055 /* Bounding box must be a list or vector containing 4 integers. */
8056 tem
= fmt
[GS_BOUNDING_BOX
].value
;
8059 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
8060 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
8065 else if (VECTORP (tem
))
8067 if (XVECTOR (tem
)->size
!= 4)
8069 for (i
= 0; i
< 4; ++i
)
8070 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
8080 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
8089 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
8090 struct gcpro gcpro1
, gcpro2
;
8092 double in_width
, in_height
;
8093 Lisp_Object pixel_colors
= Qnil
;
8095 /* Compute pixel size of pixmap needed from the given size in the
8096 image specification. Sizes in the specification are in pt. 1 pt
8097 = 1/72 in, xdpi and ydpi are stored in the frame's X display
8099 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
8100 in_width
= XFASTINT (pt_width
) / 72.0;
8101 img
->width
= in_width
* FRAME_X_DISPLAY_INFO (f
)->resx
;
8102 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
8103 in_height
= XFASTINT (pt_height
) / 72.0;
8104 img
->height
= in_height
* FRAME_X_DISPLAY_INFO (f
)->resy
;
8106 if (!check_image_size (f
, img
->width
, img
->height
))
8108 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
8112 /* Create the pixmap. */
8113 xassert (img
->pixmap
== NO_PIXMAP
);
8115 /* Only W32 version did BLOCK_INPUT here. ++kfs */
8117 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8118 img
->width
, img
->height
,
8119 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
8124 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
8128 /* Call the loader to fill the pixmap. It returns a process object
8129 if successful. We do not record_unwind_protect here because
8130 other places in redisplay like calling window scroll functions
8131 don't either. Let the Lisp loader use `unwind-protect' instead. */
8132 GCPRO2 (window_and_pixmap_id
, pixel_colors
);
8134 sprintf (buffer
, "%lu %lu",
8135 (unsigned long) FRAME_X_WINDOW (f
),
8136 (unsigned long) img
->pixmap
);
8137 window_and_pixmap_id
= build_string (buffer
);
8139 sprintf (buffer
, "%lu %lu",
8140 FRAME_FOREGROUND_PIXEL (f
),
8141 FRAME_BACKGROUND_PIXEL (f
));
8142 pixel_colors
= build_string (buffer
);
8144 XSETFRAME (frame
, f
);
8145 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
8147 loader
= intern ("gs-load-image");
8149 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
8150 make_number (img
->width
),
8151 make_number (img
->height
),
8152 window_and_pixmap_id
,
8155 return PROCESSP (img
->data
.lisp_val
);
8159 /* Kill the Ghostscript process that was started to fill PIXMAP on
8160 frame F. Called from XTread_socket when receiving an event
8161 telling Emacs that Ghostscript has finished drawing. */
8164 x_kill_gs_process (pixmap
, f
)
8168 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
8172 /* Find the image containing PIXMAP. */
8173 for (i
= 0; i
< c
->used
; ++i
)
8174 if (c
->images
[i
]->pixmap
== pixmap
)
8177 /* Should someone in between have cleared the image cache, for
8178 instance, give up. */
8182 /* Kill the GS process. We should have found PIXMAP in the image
8183 cache and its image should contain a process object. */
8185 xassert (PROCESSP (img
->data
.lisp_val
));
8186 Fkill_process (img
->data
.lisp_val
, Qnil
);
8187 img
->data
.lisp_val
= Qnil
;
8189 #if defined (HAVE_X_WINDOWS)
8191 /* On displays with a mutable colormap, figure out the colors
8192 allocated for the image by looking at the pixels of an XImage for
8194 class = FRAME_X_VISUAL (f
)->class;
8195 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
8201 /* Try to get an XImage for img->pixmep. */
8202 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
8203 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
8208 /* Initialize the color table. */
8209 init_color_table ();
8211 /* For each pixel of the image, look its color up in the
8212 color table. After having done so, the color table will
8213 contain an entry for each color used by the image. */
8214 for (y
= 0; y
< img
->height
; ++y
)
8215 for (x
= 0; x
< img
->width
; ++x
)
8217 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
8218 lookup_pixel_color (f
, pixel
);
8221 /* Record colors in the image. Free color table and XImage. */
8222 #ifdef COLOR_TABLE_SUPPORT
8223 img
->colors
= colors_in_color_table (&img
->ncolors
);
8224 free_color_table ();
8226 XDestroyImage (ximg
);
8228 #if 0 /* This doesn't seem to be the case. If we free the colors
8229 here, we get a BadAccess later in x_clear_image when
8230 freeing the colors. */
8231 /* We have allocated colors once, but Ghostscript has also
8232 allocated colors on behalf of us. So, to get the
8233 reference counts right, free them once. */
8235 x_free_colors (f
, img
->colors
, img
->ncolors
);
8239 image_error ("Cannot get X image of `%s'; colors will not be freed",
8244 #endif /* HAVE_X_WINDOWS */
8246 /* Now that we have the pixmap, compute mask and transform the
8247 image if requested. */
8249 postprocess_image (f
, img
);
8253 #endif /* HAVE_GHOSTSCRIPT */
8256 /***********************************************************************
8258 ***********************************************************************/
8262 DEFUN ("imagep", Fimagep
, Simagep
, 1, 1, 0,
8263 doc
: /* Value is non-nil if SPEC is a valid image specification. */)
8267 return valid_image_p (spec
) ? Qt
: Qnil
;
8271 DEFUN ("lookup-image", Flookup_image
, Slookup_image
, 1, 1, 0, "")
8277 if (valid_image_p (spec
))
8278 id
= lookup_image (SELECTED_FRAME (), spec
);
8281 return make_number (id
);
8284 #endif /* GLYPH_DEBUG != 0 */
8287 /***********************************************************************
8289 ***********************************************************************/
8292 /* Image types that rely on external libraries are loaded dynamically
8293 if the library is available. */
8294 #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8295 define_image_type (image_type, init_lib_fn (libraries))
8297 #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8298 define_image_type (image_type, 1)
8299 #endif /* HAVE_NTGUI */
8301 DEFUN ("init-image-library", Finit_image_library
, Sinit_image_library
, 2, 2, 0,
8302 doc
: /* Initialize image library implementing image type TYPE.
8303 Return non-nil if TYPE is a supported image type.
8305 Image types pbm and xbm are prebuilt; other types are loaded here.
8306 Libraries to load are specified in alist LIBRARIES (usually, the value
8307 of `image-library-alist', which see). */)
8309 Lisp_Object type
, libraries
;
8313 /* Don't try to reload the library. */
8314 tested
= Fassq (type
, Vimage_type_cache
);
8316 return XCDR (tested
);
8318 #if defined (HAVE_XPM) || defined (HAVE_NS)
8319 if (EQ (type
, Qxpm
))
8320 return CHECK_LIB_AVAILABLE (&xpm_type
, init_xpm_functions
, libraries
);
8323 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8324 if (EQ (type
, Qjpeg
))
8325 return CHECK_LIB_AVAILABLE (&jpeg_type
, init_jpeg_functions
, libraries
);
8328 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8329 if (EQ (type
, Qtiff
))
8330 return CHECK_LIB_AVAILABLE (&tiff_type
, init_tiff_functions
, libraries
);
8333 #if defined (HAVE_GIF) || defined (HAVE_NS)
8334 if (EQ (type
, Qgif
))
8335 return CHECK_LIB_AVAILABLE (&gif_type
, init_gif_functions
, libraries
);
8338 #if defined (HAVE_PNG) || defined (HAVE_NS)
8339 if (EQ (type
, Qpng
))
8340 return CHECK_LIB_AVAILABLE (&png_type
, init_png_functions
, libraries
);
8343 #if defined (HAVE_RSVG)
8344 if (EQ (type
, Qsvg
))
8345 return CHECK_LIB_AVAILABLE (&svg_type
, init_svg_functions
, libraries
);
8348 #ifdef HAVE_GHOSTSCRIPT
8349 if (EQ (type
, Qpostscript
))
8350 return CHECK_LIB_AVAILABLE (&gs_type
, init_gs_functions
, libraries
);
8353 /* If the type is not recognized, avoid testing it ever again. */
8354 CACHE_IMAGE_TYPE (type
, Qnil
);
8361 extern Lisp_Object Qrisky_local_variable
; /* Syms_of_xdisp has already run. */
8363 /* Initialize this only once, since that's what we do with Vimage_types
8364 and they are supposed to be in sync. Initializing here gives correct
8365 operation on GNU/Linux of calling dump-emacs after loading some images. */
8368 /* Must be defined now becase we're going to update it below, while
8369 defining the supported image types. */
8370 DEFVAR_LISP ("image-types", &Vimage_types
,
8371 doc
: /* List of potentially supported image types.
8372 Each element of the list is a symbol for an image type, like 'jpeg or 'png.
8373 To check whether it is really supported, use `image-type-available-p'. */);
8374 Vimage_types
= Qnil
;
8376 DEFVAR_LISP ("image-library-alist", &Vimage_library_alist
,
8377 doc
: /* Alist of image types vs external libraries needed to display them.
8379 Each element is a list (IMAGE-TYPE LIBRARY...), where the car is a symbol
8380 representing a supported image type, and the rest are strings giving
8381 alternate filenames for the corresponding external libraries.
8383 Emacs tries to load the libraries in the order they appear on the
8384 list; if none is loaded, the running session of Emacs won't
8385 support the image type. Types 'pbm and 'xbm don't need to be
8386 listed; they are always supported. */);
8387 Vimage_library_alist
= Qnil
;
8388 Fput (intern_c_string ("image-library-alist"), Qrisky_local_variable
, Qt
);
8390 DEFVAR_LISP ("max-image-size", &Vmax_image_size
,
8391 doc
: /* Maximum size of images.
8392 Emacs will not load an image into memory if its pixel width or
8393 pixel height exceeds this limit.
8395 If the value is an integer, it directly specifies the maximum
8396 image height and width, measured in pixels. If it is a floating
8397 point number, it specifies the maximum image height and width
8398 as a ratio to the frame height and width. If the value is
8399 non-numeric, there is no explicit limit on the size of images. */);
8400 Vmax_image_size
= make_float (MAX_IMAGE_SIZE
);
8402 Vimage_type_cache
= Qnil
;
8403 staticpro (&Vimage_type_cache
);
8405 Qpbm
= intern_c_string ("pbm");
8407 ADD_IMAGE_TYPE (Qpbm
);
8409 Qxbm
= intern_c_string ("xbm");
8411 ADD_IMAGE_TYPE (Qxbm
);
8413 define_image_type (&xbm_type
, 1);
8414 define_image_type (&pbm_type
, 1);
8416 Qcount
= intern_c_string ("count");
8417 staticpro (&Qcount
);
8419 QCascent
= intern_c_string (":ascent");
8420 staticpro (&QCascent
);
8421 QCmargin
= intern_c_string (":margin");
8422 staticpro (&QCmargin
);
8423 QCrelief
= intern_c_string (":relief");
8424 staticpro (&QCrelief
);
8425 QCconversion
= intern_c_string (":conversion");
8426 staticpro (&QCconversion
);
8427 QCcolor_symbols
= intern_c_string (":color-symbols");
8428 staticpro (&QCcolor_symbols
);
8429 QCheuristic_mask
= intern_c_string (":heuristic-mask");
8430 staticpro (&QCheuristic_mask
);
8431 QCindex
= intern_c_string (":index");
8432 staticpro (&QCindex
);
8433 QCmatrix
= intern_c_string (":matrix");
8434 staticpro (&QCmatrix
);
8435 QCcolor_adjustment
= intern_c_string (":color-adjustment");
8436 staticpro (&QCcolor_adjustment
);
8437 QCmask
= intern_c_string (":mask");
8438 staticpro (&QCmask
);
8440 Qlaplace
= intern_c_string ("laplace");
8441 staticpro (&Qlaplace
);
8442 Qemboss
= intern_c_string ("emboss");
8443 staticpro (&Qemboss
);
8444 Qedge_detection
= intern_c_string ("edge-detection");
8445 staticpro (&Qedge_detection
);
8446 Qheuristic
= intern_c_string ("heuristic");
8447 staticpro (&Qheuristic
);
8449 Qpostscript
= intern_c_string ("postscript");
8450 staticpro (&Qpostscript
);
8451 #ifdef HAVE_GHOSTSCRIPT
8452 ADD_IMAGE_TYPE (Qpostscript
);
8453 QCloader
= intern_c_string (":loader");
8454 staticpro (&QCloader
);
8455 QCbounding_box
= intern_c_string (":bounding-box");
8456 staticpro (&QCbounding_box
);
8457 QCpt_width
= intern_c_string (":pt-width");
8458 staticpro (&QCpt_width
);
8459 QCpt_height
= intern_c_string (":pt-height");
8460 staticpro (&QCpt_height
);
8461 #endif /* HAVE_GHOSTSCRIPT */
8464 Qlibpng_version
= intern_c_string ("libpng-version");
8465 staticpro (&Qlibpng_version
);
8466 Fset (Qlibpng_version
,
8468 make_number (PNG_LIBPNG_VER
)
8475 #if defined (HAVE_XPM) || defined (HAVE_NS)
8476 Qxpm
= intern_c_string ("xpm");
8478 ADD_IMAGE_TYPE (Qxpm
);
8481 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8482 Qjpeg
= intern_c_string ("jpeg");
8484 ADD_IMAGE_TYPE (Qjpeg
);
8487 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8488 Qtiff
= intern_c_string ("tiff");
8490 ADD_IMAGE_TYPE (Qtiff
);
8493 #if defined (HAVE_GIF) || defined (HAVE_NS)
8494 Qgif
= intern_c_string ("gif");
8496 ADD_IMAGE_TYPE (Qgif
);
8499 #if defined (HAVE_PNG) || defined (HAVE_NS)
8500 Qpng
= intern_c_string ("png");
8502 ADD_IMAGE_TYPE (Qpng
);
8505 #if defined (HAVE_RSVG)
8506 Qsvg
= intern_c_string ("svg");
8508 ADD_IMAGE_TYPE (Qsvg
);
8510 /* Other libraries used directly by svg code. */
8511 Qgdk_pixbuf
= intern_c_string ("gdk-pixbuf");
8512 staticpro (&Qgdk_pixbuf
);
8513 Qglib
= intern_c_string ("glib");
8515 Qgobject
= intern_c_string ("gobject");
8516 staticpro (&Qgobject
);
8517 #endif /* HAVE_NTGUI */
8518 #endif /* HAVE_RSVG */
8520 defsubr (&Sinit_image_library
);
8521 defsubr (&Sclear_image_cache
);
8522 defsubr (&Simage_refresh
);
8523 defsubr (&Simage_size
);
8524 defsubr (&Simage_mask_p
);
8525 defsubr (&Simage_extension_data
);
8529 defsubr (&Slookup_image
);
8532 DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images
,
8533 doc
: /* Non-nil means always draw a cross over disabled images.
8534 Disabled images are those having a `:conversion disabled' property.
8535 A cross is always drawn on black & white displays. */);
8536 cross_disabled_images
= 0;
8538 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
8539 doc
: /* List of directories to search for window system bitmap files. */);
8540 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
8542 DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay
,
8543 doc
: /* Time after which cached images are removed from the cache.
8544 When an image has not been displayed this many seconds, remove it
8545 from the image cache. Value must be an integer or nil with nil
8546 meaning don't clear the cache. */);
8547 Vimage_cache_eviction_delay
= make_number (30 * 60);
8555 /* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9
8556 (do not change this comment) */