1 /* Functions for image support on window system.
2 Copyright (C) 1989, 1992-2011 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
26 #if defined HAVE_LIBPNG_PNG_H
27 # include <libpng/png.h>
35 /* This makes the fields of a Display accessible, in Xlib header files. */
37 #define XLIB_ILLEGAL_ACCESS
42 #include "dispextern.h"
43 #include "blockinput.h"
46 #include "character.h"
48 #include "termhooks.h"
53 #include <sys/types.h>
56 #define COLOR_TABLE_SUPPORT 1
58 typedef struct x_bitmap_record Bitmap_Record
;
59 #define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
60 #define NO_PIXMAP None
62 #define RGB_PIXEL_COLOR unsigned long
64 #define PIX_MASK_RETAIN 0
65 #define PIX_MASK_DRAW 1
66 #endif /* HAVE_X_WINDOWS */
73 /* W32_TODO : Color tables on W32. */
74 #undef COLOR_TABLE_SUPPORT
76 typedef struct w32_bitmap_record Bitmap_Record
;
77 #define GET_PIXEL(ximg, x, y) GetPixel(ximg, x, y)
80 #define RGB_PIXEL_COLOR COLORREF
82 #define PIX_MASK_RETAIN 0
83 #define PIX_MASK_DRAW 1
85 #define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual
86 #define x_defined_color w32_defined_color
87 #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
89 /* Functions from w32term.c that depend on XColor (so can't go in w32term.h
90 without modifying lots of files). */
91 extern void x_query_colors (struct frame
*f
, XColor
*colors
, int ncolors
);
92 extern void x_query_color (struct frame
*f
, XColor
*color
);
94 /* Version of libpng that we were compiled with, or -1 if no PNG
95 support was compiled in. This is tested by w32-win.el to correctly
96 set up the alist used to search for PNG libraries. */
97 Lisp_Object Qlibpng_version
;
98 #endif /* HAVE_NTGUI */
102 #include <sys/types.h>
103 #include <sys/stat.h>
105 #undef COLOR_TABLE_SUPPORT
107 typedef struct ns_bitmap_record Bitmap_Record
;
109 #define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
112 #define RGB_PIXEL_COLOR unsigned long
115 #define PIX_MASK_RETAIN 0
116 #define PIX_MASK_DRAW 1
118 #define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO(f)->visual
119 #define x_defined_color(f, name, color_def, alloc) \
120 ns_defined_color (f, name, color_def, alloc, 0)
121 #define FRAME_X_SCREEN(f) 0
122 #define DefaultDepthOfScreen(screen) x_display_list->n_planes
126 /* The symbol `postscript' identifying images of this type. */
128 static Lisp_Object Qpostscript
;
130 static void x_disable_image (struct frame
*, struct image
*);
131 static void x_edge_detection (struct frame
*, struct image
*, Lisp_Object
,
134 static void init_color_table (void);
135 static unsigned long lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
);
136 #ifdef COLOR_TABLE_SUPPORT
137 static void free_color_table (void);
138 static unsigned long *colors_in_color_table (int *n
);
139 static unsigned long lookup_pixel_color (struct frame
*f
, unsigned long p
);
141 static Lisp_Object
Finit_image_library (Lisp_Object
, Lisp_Object
);
143 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
144 id, which is just an int that this section returns. Bitmaps are
145 reference counted so they can be shared among frames.
147 Bitmap indices are guaranteed to be > 0, so a negative number can
148 be used to indicate no bitmap.
150 If you use x_create_bitmap_from_data, then you must keep track of
151 the bitmaps yourself. That is, creating a bitmap from the same
152 data more than once will not be caught. */
156 XGetImage (Display
*display
, Pixmap pixmap
, int x
, int y
,
157 unsigned int width
, unsigned int height
,
158 unsigned long plane_mask
, int format
)
160 /* TODO: not sure what this function is supposed to do.. */
161 ns_retain_object (pixmap
);
165 /* use with imgs created by ns_image_for_XPM */
167 XGetPixel (XImagePtr ximage
, int x
, int y
)
169 return ns_get_pixel (ximage
, x
, y
);
172 /* use with imgs created by ns_image_for_XPM; alpha set to 1;
173 pixel is assumed to be in form RGB */
175 XPutPixel (XImagePtr ximage
, int x
, int y
, unsigned long pixel
)
177 ns_put_pixel (ximage
, x
, y
, pixel
);
182 /* Functions to access the contents of a bitmap, given an id. */
185 x_bitmap_height (FRAME_PTR f
, int id
)
187 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
191 x_bitmap_width (FRAME_PTR f
, int id
)
193 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
196 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
198 x_bitmap_pixmap (FRAME_PTR f
, int id
)
200 return (int) FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
204 #ifdef HAVE_X_WINDOWS
206 x_bitmap_mask (FRAME_PTR f
, int id
)
208 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].mask
;
212 /* Allocate a new bitmap record. Returns index of new record. */
215 x_allocate_bitmap_record (FRAME_PTR f
)
217 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
220 if (dpyinfo
->bitmaps
== NULL
)
222 dpyinfo
->bitmaps_size
= 10;
224 = (Bitmap_Record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (Bitmap_Record
));
225 dpyinfo
->bitmaps_last
= 1;
229 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
230 return ++dpyinfo
->bitmaps_last
;
232 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
233 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
236 dpyinfo
->bitmaps_size
*= 2;
238 = (Bitmap_Record
*) xrealloc (dpyinfo
->bitmaps
,
239 dpyinfo
->bitmaps_size
* sizeof (Bitmap_Record
));
240 return ++dpyinfo
->bitmaps_last
;
243 /* Add one reference to the reference count of the bitmap with id ID. */
246 x_reference_bitmap (FRAME_PTR f
, int id
)
248 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
251 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
254 x_create_bitmap_from_data (struct frame
*f
, char *bits
, unsigned int width
, unsigned int height
)
256 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
259 #ifdef HAVE_X_WINDOWS
261 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
262 bits
, width
, height
);
265 #endif /* HAVE_X_WINDOWS */
269 bitmap
= CreateBitmap (width
, height
,
270 FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_planes
,
271 FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_cbits
,
275 #endif /* HAVE_NTGUI */
278 void *bitmap
= ns_image_from_XBM (bits
, width
, height
);
283 id
= x_allocate_bitmap_record (f
);
286 dpyinfo
->bitmaps
[id
- 1].img
= bitmap
;
287 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
290 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
291 dpyinfo
->bitmaps
[id
- 1].height
= height
;
292 dpyinfo
->bitmaps
[id
- 1].width
= width
;
293 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
295 #ifdef HAVE_X_WINDOWS
296 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
297 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
298 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
299 #endif /* HAVE_X_WINDOWS */
302 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
303 dpyinfo
->bitmaps
[id
- 1].hinst
= NULL
;
304 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
305 #endif /* HAVE_NTGUI */
310 /* Create bitmap from file FILE for frame F. */
313 x_create_bitmap_from_file (struct frame
*f
, Lisp_Object file
)
315 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
318 return -1; /* W32_TODO : bitmap support */
319 #endif /* HAVE_NTGUI */
323 void *bitmap
= ns_image_from_file (file
);
329 id
= x_allocate_bitmap_record (f
);
330 dpyinfo
->bitmaps
[id
- 1].img
= bitmap
;
331 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
332 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (SBYTES (file
) + 1);
333 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
334 dpyinfo
->bitmaps
[id
- 1].height
= ns_image_width (bitmap
);
335 dpyinfo
->bitmaps
[id
- 1].width
= ns_image_height (bitmap
);
336 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
340 #ifdef HAVE_X_WINDOWS
341 unsigned int width
, height
;
343 int xhot
, yhot
, result
, id
;
348 /* Look for an existing bitmap with the same name. */
349 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
351 if (dpyinfo
->bitmaps
[id
].refcount
352 && dpyinfo
->bitmaps
[id
].file
353 && !strcmp (dpyinfo
->bitmaps
[id
].file
, SSDATA (file
)))
355 ++dpyinfo
->bitmaps
[id
].refcount
;
360 /* Search bitmap-file-path for the file, if appropriate. */
361 fd
= openp (Vx_bitmap_file_path
, file
, Qnil
, &found
, Qnil
);
366 filename
= SSDATA (found
);
368 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
369 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
370 if (result
!= BitmapSuccess
)
373 id
= x_allocate_bitmap_record (f
);
374 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
375 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
376 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
377 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (SBYTES (file
) + 1);
378 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
379 dpyinfo
->bitmaps
[id
- 1].height
= height
;
380 dpyinfo
->bitmaps
[id
- 1].width
= width
;
381 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SSDATA (file
));
384 #endif /* HAVE_X_WINDOWS */
390 free_bitmap_record (Display_Info
*dpyinfo
, Bitmap_Record
*bm
)
392 #ifdef HAVE_X_WINDOWS
393 XFreePixmap (dpyinfo
->display
, bm
->pixmap
);
395 XFreePixmap (dpyinfo
->display
, bm
->mask
);
396 #endif /* HAVE_X_WINDOWS */
399 DeleteObject (bm
->pixmap
);
400 #endif /* HAVE_NTGUI */
403 ns_release_object (bm
->img
);
413 /* Remove reference to bitmap with id number ID. */
416 x_destroy_bitmap (FRAME_PTR f
, int id
)
418 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
422 Bitmap_Record
*bm
= &dpyinfo
->bitmaps
[id
- 1];
424 if (--bm
->refcount
== 0)
427 free_bitmap_record (dpyinfo
, bm
);
433 /* Free all the bitmaps for the display specified by DPYINFO. */
436 x_destroy_all_bitmaps (Display_Info
*dpyinfo
)
439 Bitmap_Record
*bm
= dpyinfo
->bitmaps
;
441 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++, bm
++)
442 if (bm
->refcount
> 0)
443 free_bitmap_record (dpyinfo
, bm
);
445 dpyinfo
->bitmaps_last
= 0;
449 #ifdef HAVE_X_WINDOWS
451 /* Useful functions defined in the section
452 `Image type independent image structures' below. */
454 static unsigned long four_corners_best (XImagePtr ximg
,
457 unsigned long height
);
459 static int x_create_x_image_and_pixmap (struct frame
*f
, int width
, int height
,
460 int depth
, XImagePtr
*ximg
,
463 static void x_destroy_x_image (XImagePtr ximg
);
466 /* Create a mask of a bitmap. Note is this not a perfect mask.
467 It's nicer with some borders in this context */
470 x_create_bitmap_mask (struct frame
*f
, int id
)
473 XImagePtr ximg
, mask_img
;
474 unsigned long width
, height
;
477 unsigned long x
, y
, xp
, xm
, yp
, ym
;
480 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
485 pixmap
= x_bitmap_pixmap (f
, id
);
486 width
= x_bitmap_width (f
, id
);
487 height
= x_bitmap_height (f
, id
);
490 ximg
= XGetImage (FRAME_X_DISPLAY (f
), pixmap
, 0, 0, width
, height
,
499 result
= x_create_x_image_and_pixmap (f
, width
, height
, 1, &mask_img
, &mask
);
504 XDestroyImage (ximg
);
508 bg
= four_corners_best (ximg
, NULL
, width
, height
);
510 for (y
= 0; y
< ximg
->height
; ++y
)
512 for (x
= 0; x
< ximg
->width
; ++x
)
514 xp
= x
!= ximg
->width
- 1 ? x
+ 1 : 0;
515 xm
= x
!= 0 ? x
- 1 : ximg
->width
- 1;
516 yp
= y
!= ximg
->height
- 1 ? y
+ 1 : 0;
517 ym
= y
!= 0 ? y
- 1 : ximg
->height
- 1;
518 if (XGetPixel (ximg
, x
, y
) == bg
519 && XGetPixel (ximg
, x
, yp
) == bg
520 && XGetPixel (ximg
, x
, ym
) == bg
521 && XGetPixel (ximg
, xp
, y
) == bg
522 && XGetPixel (ximg
, xp
, yp
) == bg
523 && XGetPixel (ximg
, xp
, ym
) == bg
524 && XGetPixel (ximg
, xm
, y
) == bg
525 && XGetPixel (ximg
, xm
, yp
) == bg
526 && XGetPixel (ximg
, xm
, ym
) == bg
)
527 XPutPixel (mask_img
, x
, y
, 0);
529 XPutPixel (mask_img
, x
, y
, 1);
533 xassert (interrupt_input_blocked
);
534 gc
= XCreateGC (FRAME_X_DISPLAY (f
), mask
, 0, NULL
);
535 XPutImage (FRAME_X_DISPLAY (f
), mask
, gc
, mask_img
, 0, 0, 0, 0,
537 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
539 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
540 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
542 XDestroyImage (ximg
);
543 x_destroy_x_image (mask_img
);
548 #endif /* HAVE_X_WINDOWS */
551 /***********************************************************************
553 ***********************************************************************/
555 /* List of supported image types. Use define_image_type to add new
556 types. Use lookup_image_type to find a type for a given symbol. */
558 static struct image_type
*image_types
;
560 /* The symbol `xbm' which is used as the type symbol for XBM images. */
562 static Lisp_Object Qxbm
;
566 Lisp_Object QCascent
, QCmargin
, QCrelief
;
567 Lisp_Object QCconversion
;
568 static Lisp_Object QCheuristic_mask
;
569 static Lisp_Object QCcolor_symbols
;
570 static Lisp_Object QCindex
, QCmatrix
, QCcolor_adjustment
, QCmask
, QCgeometry
;
571 static Lisp_Object QCcrop
, QCrotation
;
575 static Lisp_Object Qcount
, Qextension_data
, Qdelay
;
576 static Lisp_Object Qlaplace
, Qemboss
, Qedge_detection
, Qheuristic
;
578 /* Function prototypes. */
580 static Lisp_Object
define_image_type (struct image_type
*type
, int loaded
);
581 static struct image_type
*lookup_image_type (Lisp_Object symbol
);
582 static void image_error (const char *format
, Lisp_Object
, Lisp_Object
);
583 static void x_laplace (struct frame
*, struct image
*);
584 static void x_emboss (struct frame
*, struct image
*);
585 static int x_build_heuristic_mask (struct frame
*, struct image
*,
588 #define CACHE_IMAGE_TYPE(type, status) \
589 do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
591 #define CACHE_IMAGE_TYPE(type, status)
594 #define ADD_IMAGE_TYPE(type) \
595 do { Vimage_types = Fcons (type, Vimage_types); } while (0)
597 /* Define a new image type from TYPE. This adds a copy of TYPE to
598 image_types and caches the loading status of TYPE. */
601 define_image_type (struct image_type
*type
, int loaded
)
609 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
610 The initialized data segment is read-only. */
611 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
612 memcpy (p
, type
, sizeof *p
);
613 p
->next
= image_types
;
618 CACHE_IMAGE_TYPE (*type
->type
, success
);
623 /* Look up image type SYMBOL, and return a pointer to its image_type
624 structure. Value is null if SYMBOL is not a known image type. */
626 static inline struct image_type
*
627 lookup_image_type (Lisp_Object symbol
)
629 struct image_type
*type
;
631 /* We must initialize the image-type if it hasn't been already. */
632 if (NILP (Finit_image_library (symbol
, Vdynamic_library_alist
)))
633 return 0; /* unimplemented */
635 for (type
= image_types
; type
; type
= type
->next
)
636 if (EQ (symbol
, *type
->type
))
643 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
644 valid image specification is a list whose car is the symbol
645 `image', and whose rest is a property list. The property list must
646 contain a value for key `:type'. That value must be the name of a
647 supported image type. The rest of the property list depends on the
651 valid_image_p (Lisp_Object object
)
659 for (tem
= XCDR (object
); CONSP (tem
); tem
= XCDR (tem
))
660 if (EQ (XCAR (tem
), QCtype
))
663 if (CONSP (tem
) && SYMBOLP (XCAR (tem
)))
665 struct image_type
*type
;
666 type
= lookup_image_type (XCAR (tem
));
668 valid_p
= type
->valid_p (object
);
679 /* Log error message with format string FORMAT and argument ARG.
680 Signaling an error, e.g. when an image cannot be loaded, is not a
681 good idea because this would interrupt redisplay, and the error
682 message display would lead to another redisplay. This function
683 therefore simply displays a message. */
686 image_error (const char *format
, Lisp_Object arg1
, Lisp_Object arg2
)
688 add_to_log (format
, arg1
, arg2
);
693 /***********************************************************************
695 ***********************************************************************/
697 enum image_value_type
699 IMAGE_DONT_CHECK_VALUE_TYPE
,
701 IMAGE_STRING_OR_NIL_VALUE
,
703 IMAGE_POSITIVE_INTEGER_VALUE
,
704 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
705 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
708 IMAGE_FUNCTION_VALUE
,
713 /* Structure used when parsing image specifications. */
717 /* Name of keyword. */
720 /* The type of value allowed. */
721 enum image_value_type type
;
723 /* Non-zero means key must be present. */
726 /* Used to recognize duplicate keywords in a property list. */
729 /* The value that was found. */
734 static int parse_image_spec (Lisp_Object
, struct image_keyword
*,
736 static Lisp_Object
image_spec_value (Lisp_Object
, Lisp_Object
, int *);
739 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
740 has the format (image KEYWORD VALUE ...). One of the keyword/
741 value pairs must be `:type TYPE'. KEYWORDS is a vector of
742 image_keywords structures of size NKEYWORDS describing other
743 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
746 parse_image_spec (Lisp_Object spec
, struct image_keyword
*keywords
,
747 int nkeywords
, Lisp_Object type
)
756 while (CONSP (plist
))
758 Lisp_Object key
, value
;
760 /* First element of a pair must be a symbol. */
762 plist
= XCDR (plist
);
766 /* There must follow a value. */
769 value
= XCAR (plist
);
770 plist
= XCDR (plist
);
772 /* Find key in KEYWORDS. Error if not found. */
773 for (i
= 0; i
< nkeywords
; ++i
)
774 if (strcmp (keywords
[i
].name
, SSDATA (SYMBOL_NAME (key
))) == 0)
780 /* Record that we recognized the keyword. If a keywords
781 was found more than once, it's an error. */
782 keywords
[i
].value
= value
;
785 if (keywords
[i
].count
> 1)
788 /* Check type of value against allowed type. */
789 switch (keywords
[i
].type
)
791 case IMAGE_STRING_VALUE
:
792 if (!STRINGP (value
))
796 case IMAGE_STRING_OR_NIL_VALUE
:
797 if (!STRINGP (value
) && !NILP (value
))
801 case IMAGE_SYMBOL_VALUE
:
802 if (!SYMBOLP (value
))
806 case IMAGE_POSITIVE_INTEGER_VALUE
:
807 if (!INTEGERP (value
) || XINT (value
) <= 0)
811 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
812 if (INTEGERP (value
) && XINT (value
) >= 0)
815 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
816 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
820 case IMAGE_ASCENT_VALUE
:
821 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
823 else if (INTEGERP (value
)
825 && XINT (value
) <= 100)
829 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
830 if (!INTEGERP (value
) || XINT (value
) < 0)
834 case IMAGE_DONT_CHECK_VALUE_TYPE
:
837 case IMAGE_FUNCTION_VALUE
:
838 value
= indirect_function (value
);
839 if (!NILP (Ffunctionp (value
)))
843 case IMAGE_NUMBER_VALUE
:
844 if (!INTEGERP (value
) && !FLOATP (value
))
848 case IMAGE_INTEGER_VALUE
:
849 if (!INTEGERP (value
))
853 case IMAGE_BOOL_VALUE
:
854 if (!NILP (value
) && !EQ (value
, Qt
))
863 if (EQ (key
, QCtype
) && !EQ (type
, value
))
867 /* Check that all mandatory fields are present. */
868 for (i
= 0; i
< nkeywords
; ++i
)
869 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
876 /* Return the value of KEY in image specification SPEC. Value is nil
877 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
878 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
881 image_spec_value (Lisp_Object spec
, Lisp_Object key
, int *found
)
885 xassert (valid_image_p (spec
));
887 for (tail
= XCDR (spec
);
888 CONSP (tail
) && CONSP (XCDR (tail
));
889 tail
= XCDR (XCDR (tail
)))
891 if (EQ (XCAR (tail
), key
))
895 return XCAR (XCDR (tail
));
905 DEFUN ("image-size", Fimage_size
, Simage_size
, 1, 3, 0,
906 doc
: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
907 PIXELS non-nil means return the size in pixels, otherwise return the
908 size in canonical character units.
909 FRAME is the frame on which the image will be displayed. FRAME nil
910 or omitted means use the selected frame. */)
911 (Lisp_Object spec
, Lisp_Object pixels
, Lisp_Object frame
)
916 if (valid_image_p (spec
))
918 struct frame
*f
= check_x_frame (frame
);
919 int id
= lookup_image (f
, spec
);
920 struct image
*img
= IMAGE_FROM_ID (f
, id
);
921 int width
= img
->width
+ 2 * img
->hmargin
;
922 int height
= img
->height
+ 2 * img
->vmargin
;
925 size
= Fcons (make_float ((double) width
/ FRAME_COLUMN_WIDTH (f
)),
926 make_float ((double) height
/ FRAME_LINE_HEIGHT (f
)));
928 size
= Fcons (make_number (width
), make_number (height
));
931 error ("Invalid image specification");
937 DEFUN ("image-mask-p", Fimage_mask_p
, Simage_mask_p
, 1, 2, 0,
938 doc
: /* Return t if image SPEC has a mask bitmap.
939 FRAME is the frame on which the image will be displayed. FRAME nil
940 or omitted means use the selected frame. */)
941 (Lisp_Object spec
, Lisp_Object frame
)
946 if (valid_image_p (spec
))
948 struct frame
*f
= check_x_frame (frame
);
949 int id
= lookup_image (f
, spec
);
950 struct image
*img
= IMAGE_FROM_ID (f
, id
);
955 error ("Invalid image specification");
960 DEFUN ("image-metadata", Fimage_metadata
, Simage_metadata
, 1, 2, 0,
961 doc
: /* Return metadata for image SPEC.
962 FRAME is the frame on which the image will be displayed. FRAME nil
963 or omitted means use the selected frame. */)
964 (Lisp_Object spec
, Lisp_Object frame
)
969 if (valid_image_p (spec
))
971 struct frame
*f
= check_x_frame (frame
);
972 int id
= lookup_image (f
, spec
);
973 struct image
*img
= IMAGE_FROM_ID (f
, id
);
974 ext
= img
->lisp_data
;
981 /***********************************************************************
982 Image type independent image structures
983 ***********************************************************************/
985 static void free_image (struct frame
*f
, struct image
*img
);
986 static int check_image_size (struct frame
*f
, int width
, int height
);
988 #define MAX_IMAGE_SIZE 6.0
989 /* Allocate and return a new image structure for image specification
990 SPEC. SPEC has a hash value of HASH. */
992 static struct image
*
993 make_image (Lisp_Object spec
, EMACS_UINT hash
)
995 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
996 Lisp_Object file
= image_spec_value (spec
, QCfile
, NULL
);
998 xassert (valid_image_p (spec
));
999 memset (img
, 0, sizeof *img
);
1000 img
->dependencies
= NILP (file
) ? Qnil
: list1 (file
);
1001 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
1002 xassert (img
->type
!= NULL
);
1004 img
->lisp_data
= Qnil
;
1005 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
1007 img
->corners
[BOT_CORNER
] = -1; /* Full image */
1012 /* Free image IMG which was used on frame F, including its resources. */
1015 free_image (struct frame
*f
, struct image
*img
)
1019 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1021 /* Remove IMG from the hash table of its cache. */
1023 img
->prev
->next
= img
->next
;
1025 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
1028 img
->next
->prev
= img
->prev
;
1030 c
->images
[img
->id
] = NULL
;
1032 /* Free resources, then free IMG. */
1033 img
->type
->free (f
, img
);
1038 /* Return 1 if the given widths and heights are valid for display;
1039 otherwise, return 0. */
1042 check_image_size (struct frame
*f
, int width
, int height
)
1046 if (width
<= 0 || height
<= 0)
1049 if (INTEGERP (Vmax_image_size
))
1050 w
= h
= XINT (Vmax_image_size
);
1051 else if (FLOATP (Vmax_image_size
))
1055 w
= FRAME_PIXEL_WIDTH (f
);
1056 h
= FRAME_PIXEL_HEIGHT (f
);
1059 w
= h
= 1024; /* Arbitrary size for unknown frame. */
1060 w
= (int) (XFLOAT_DATA (Vmax_image_size
) * w
);
1061 h
= (int) (XFLOAT_DATA (Vmax_image_size
) * h
);
1066 return (width
<= w
&& height
<= h
);
1069 /* Prepare image IMG for display on frame F. Must be called before
1070 drawing an image. */
1073 prepare_image_for_display (struct frame
*f
, struct image
*img
)
1077 /* We're about to display IMG, so set its timestamp to `now'. */
1079 img
->timestamp
= EMACS_SECS (t
);
1081 /* If IMG doesn't have a pixmap yet, load it now, using the image
1082 type dependent loader function. */
1083 if (img
->pixmap
== NO_PIXMAP
&& !img
->load_failed_p
)
1084 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
1089 /* Value is the number of pixels for the ascent of image IMG when
1090 drawn in face FACE. */
1093 image_ascent (struct image
*img
, struct face
*face
, struct glyph_slice
*slice
)
1098 if (slice
->height
== img
->height
)
1099 height
= img
->height
+ img
->vmargin
;
1100 else if (slice
->y
== 0)
1101 height
= slice
->height
+ img
->vmargin
;
1103 height
= slice
->height
;
1105 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
1110 /* W32 specific version. Why?. ++kfs */
1111 ascent
= height
/ 2 - (FONT_DESCENT (face
->font
)
1112 - FONT_BASE (face
->font
)) / 2;
1114 /* This expression is arranged so that if the image can't be
1115 exactly centered, it will be moved slightly up. This is
1116 because a typical font is `top-heavy' (due to the presence
1117 uppercase letters), so the image placement should err towards
1118 being top-heavy too. It also just generally looks better. */
1119 ascent
= (height
+ FONT_BASE(face
->font
)
1120 - FONT_DESCENT(face
->font
) + 1) / 2;
1121 #endif /* HAVE_NTGUI */
1124 ascent
= height
/ 2;
1127 ascent
= (int) (height
* img
->ascent
/ 100.0);
1133 /* Image background colors. */
1135 /* Find the "best" corner color of a bitmap.
1136 On W32, XIMG is assumed to a device context with the bitmap selected. */
1138 static RGB_PIXEL_COLOR
1139 four_corners_best (XImagePtr_or_DC ximg
, int *corners
,
1140 unsigned long width
, unsigned long height
)
1142 RGB_PIXEL_COLOR corner_pixels
[4], best
IF_LINT (= 0);
1145 if (corners
&& corners
[BOT_CORNER
] >= 0)
1147 /* Get the colors at the corner_pixels of ximg. */
1148 corner_pixels
[0] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[TOP_CORNER
]);
1149 corner_pixels
[1] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[TOP_CORNER
]);
1150 corner_pixels
[2] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[BOT_CORNER
] - 1);
1151 corner_pixels
[3] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[BOT_CORNER
] - 1);
1155 /* Get the colors at the corner_pixels of ximg. */
1156 corner_pixels
[0] = GET_PIXEL (ximg
, 0, 0);
1157 corner_pixels
[1] = GET_PIXEL (ximg
, width
- 1, 0);
1158 corner_pixels
[2] = GET_PIXEL (ximg
, width
- 1, height
- 1);
1159 corner_pixels
[3] = GET_PIXEL (ximg
, 0, height
- 1);
1161 /* Choose the most frequently found color as background. */
1162 for (i
= best_count
= 0; i
< 4; ++i
)
1166 for (j
= n
= 0; j
< 4; ++j
)
1167 if (corner_pixels
[i
] == corner_pixels
[j
])
1171 best
= corner_pixels
[i
], best_count
= n
;
1177 /* Portability macros */
1181 #define Destroy_Image(img_dc, prev) \
1182 do { SelectObject (img_dc, prev); DeleteDC (img_dc); } while (0)
1184 #define Free_Pixmap(display, pixmap) \
1185 DeleteObject (pixmap)
1187 #elif defined (HAVE_NS)
1189 #define Destroy_Image(ximg, dummy) \
1190 ns_release_object (ximg)
1192 #define Free_Pixmap(display, pixmap) \
1193 ns_release_object (pixmap)
1197 #define Destroy_Image(ximg, dummy) \
1198 XDestroyImage (ximg)
1200 #define Free_Pixmap(display, pixmap) \
1201 XFreePixmap (display, pixmap)
1203 #endif /* !HAVE_NTGUI && !HAVE_NS */
1206 /* Return the `background' field of IMG. If IMG doesn't have one yet,
1207 it is guessed heuristically. If non-zero, XIMG is an existing
1208 XImage object (or device context with the image selected on W32) to
1209 use for the heuristic. */
1212 image_background (struct image
*img
, struct frame
*f
, XImagePtr_or_DC ximg
)
1214 if (! img
->background_valid
)
1215 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1217 int free_ximg
= !ximg
;
1220 #endif /* HAVE_NTGUI */
1225 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
1226 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
1228 HDC frame_dc
= get_frame_dc (f
);
1229 ximg
= CreateCompatibleDC (frame_dc
);
1230 release_frame_dc (f
, frame_dc
);
1231 prev
= SelectObject (ximg
, img
->pixmap
);
1232 #endif /* !HAVE_NTGUI */
1235 img
->background
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
1238 Destroy_Image (ximg
, prev
);
1240 img
->background_valid
= 1;
1243 return img
->background
;
1246 /* Return the `background_transparent' field of IMG. If IMG doesn't
1247 have one yet, it is guessed heuristically. If non-zero, MASK is an
1248 existing XImage object to use for the heuristic. */
1251 image_background_transparent (struct image
*img
, struct frame
*f
, XImagePtr_or_DC mask
)
1253 if (! img
->background_transparent_valid
)
1254 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1258 int free_mask
= !mask
;
1261 #endif /* HAVE_NTGUI */
1266 mask
= XGetImage (FRAME_X_DISPLAY (f
), img
->mask
,
1267 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
1269 HDC frame_dc
= get_frame_dc (f
);
1270 mask
= CreateCompatibleDC (frame_dc
);
1271 release_frame_dc (f
, frame_dc
);
1272 prev
= SelectObject (mask
, img
->mask
);
1273 #endif /* HAVE_NTGUI */
1276 img
->background_transparent
1277 = (four_corners_best (mask
, img
->corners
, img
->width
, img
->height
) == PIX_MASK_RETAIN
);
1280 Destroy_Image (mask
, prev
);
1283 img
->background_transparent
= 0;
1285 img
->background_transparent_valid
= 1;
1288 return img
->background_transparent
;
1292 /***********************************************************************
1293 Helper functions for X image types
1294 ***********************************************************************/
1296 static void x_clear_image_1 (struct frame
*, struct image
*, int,
1298 static void x_clear_image (struct frame
*f
, struct image
*img
);
1299 static unsigned long x_alloc_image_color (struct frame
*f
,
1301 Lisp_Object color_name
,
1302 unsigned long dflt
);
1305 /* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
1306 free the pixmap if any. MASK_P non-zero means clear the mask
1307 pixmap if any. COLORS_P non-zero means free colors allocated for
1308 the image, if any. */
1311 x_clear_image_1 (struct frame
*f
, struct image
*img
, int pixmap_p
, int mask_p
,
1314 if (pixmap_p
&& img
->pixmap
)
1316 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
1317 img
->pixmap
= NO_PIXMAP
;
1318 /* NOTE (HAVE_NS): background color is NOT an indexed color! */
1319 img
->background_valid
= 0;
1322 if (mask_p
&& img
->mask
)
1324 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
1325 img
->mask
= NO_PIXMAP
;
1326 img
->background_transparent_valid
= 0;
1329 if (colors_p
&& img
->ncolors
)
1331 /* W32_TODO: color table support. */
1332 #ifdef HAVE_X_WINDOWS
1333 x_free_colors (f
, img
->colors
, img
->ncolors
);
1334 #endif /* HAVE_X_WINDOWS */
1335 xfree (img
->colors
);
1342 /* Free X resources of image IMG which is used on frame F. */
1345 x_clear_image (struct frame
*f
, struct image
*img
)
1348 x_clear_image_1 (f
, img
, 1, 1, 1);
1353 /* Allocate color COLOR_NAME for image IMG on frame F. If color
1354 cannot be allocated, use DFLT. Add a newly allocated color to
1355 IMG->colors, so that it can be freed again. Value is the pixel
1358 static unsigned long
1359 x_alloc_image_color (struct frame
*f
, struct image
*img
, Lisp_Object color_name
,
1363 unsigned long result
;
1365 xassert (STRINGP (color_name
));
1367 if (x_defined_color (f
, SSDATA (color_name
), &color
, 1))
1369 /* This isn't called frequently so we get away with simply
1370 reallocating the color vector to the needed size, here. */
1373 (unsigned long *) xrealloc (img
->colors
,
1374 img
->ncolors
* sizeof *img
->colors
);
1375 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
1376 result
= color
.pixel
;
1386 /***********************************************************************
1388 ***********************************************************************/
1390 static void cache_image (struct frame
*f
, struct image
*img
);
1391 static void postprocess_image (struct frame
*, struct image
*);
1393 /* Return a new, initialized image cache that is allocated from the
1394 heap. Call free_image_cache to free an image cache. */
1396 struct image_cache
*
1397 make_image_cache (void)
1399 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
1402 memset (c
, 0, sizeof *c
);
1404 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
1405 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
1406 c
->buckets
= (struct image
**) xmalloc (size
);
1407 memset (c
->buckets
, 0, size
);
1412 /* Find an image matching SPEC in the cache, and return it. If no
1413 image is found, return NULL. */
1414 static struct image
*
1415 search_image_cache (struct frame
*f
, Lisp_Object spec
, EMACS_UINT hash
)
1418 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1419 int i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1421 if (!c
) return NULL
;
1423 /* If the image spec does not specify a background color, the cached
1424 image must have the same background color as the current frame.
1425 The foreground color must also match, for the sake of monochrome
1428 In fact, we could ignore the foreground color matching condition
1429 for color images, or if the image spec specifies :foreground;
1430 similarly we could ignore the background color matching condition
1431 for formats that don't use transparency (such as jpeg), or if the
1432 image spec specifies :background. However, the extra memory
1433 usage is probably negligible in practice, so we don't bother. */
1435 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
1436 if (img
->hash
== hash
1437 && !NILP (Fequal (img
->spec
, spec
))
1438 && img
->frame_foreground
== FRAME_FOREGROUND_PIXEL (f
)
1439 && img
->frame_background
== FRAME_BACKGROUND_PIXEL (f
))
1445 /* Search frame F for an image with spec SPEC, and free it. */
1448 uncache_image (struct frame
*f
, Lisp_Object spec
)
1450 struct image
*img
= search_image_cache (f
, spec
, sxhash (spec
, 0));
1453 free_image (f
, img
);
1454 /* As display glyphs may still be referring to the image ID, we
1455 must garbage the frame (Bug#6426). */
1456 SET_FRAME_GARBAGED (f
);
1461 /* Free image cache of frame F. Be aware that X frames share images
1465 free_image_cache (struct frame
*f
)
1467 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1472 /* Cache should not be referenced by any frame when freed. */
1473 xassert (c
->refcount
== 0);
1475 for (i
= 0; i
< c
->used
; ++i
)
1476 free_image (f
, c
->images
[i
]);
1480 FRAME_IMAGE_CACHE (f
) = NULL
;
1485 /* Clear image cache of frame F. FILTER=t means free all images.
1486 FILTER=nil means clear only images that haven't been
1487 displayed for some time.
1488 Else, only free the images which have FILTER in their `dependencies'.
1489 Should be called from time to time to reduce the number of loaded images.
1490 If image-cache-eviction-delay is non-nil, this frees images in the cache
1491 which weren't displayed for at least that many seconds. */
1494 clear_image_cache (struct frame
*f
, Lisp_Object filter
)
1496 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1502 /* Block input so that we won't be interrupted by a SIGIO
1503 while being in an inconsistent state. */
1508 /* Filter image cache. */
1509 for (i
= 0; i
< c
->used
; ++i
)
1511 struct image
*img
= c
->images
[i
];
1512 if (img
&& (EQ (Qt
, filter
)
1513 || !NILP (Fmember (filter
, img
->dependencies
))))
1515 free_image (f
, img
);
1520 else if (INTEGERP (Vimage_cache_eviction_delay
))
1522 /* Free cache based on timestamp. */
1525 int delay
, nimages
= 0;
1527 for (i
= 0; i
< c
->used
; ++i
)
1531 /* If the number of cached images has grown unusually large,
1532 decrease the cache eviction delay (Bug#6230). */
1533 delay
= XFASTINT (Vimage_cache_eviction_delay
);
1535 delay
= max (1, 1600 * delay
/ (nimages
*nimages
));
1538 old
= EMACS_SECS (t
) - delay
;
1540 for (i
= 0; i
< c
->used
; ++i
)
1542 struct image
*img
= c
->images
[i
];
1543 if (img
&& img
->timestamp
< old
)
1545 free_image (f
, img
);
1551 /* We may be clearing the image cache because, for example,
1552 Emacs was iconified for a longer period of time. In that
1553 case, current matrices may still contain references to
1554 images freed above. So, clear these matrices. */
1557 Lisp_Object tail
, frame
;
1559 FOR_EACH_FRAME (tail
, frame
)
1561 struct frame
*fr
= XFRAME (frame
);
1562 if (FRAME_IMAGE_CACHE (fr
) == c
)
1563 clear_current_matrices (fr
);
1566 ++windows_or_buffers_changed
;
1574 clear_image_caches (Lisp_Object filter
)
1576 /* FIXME: We want to do
1577 * struct terminal *t;
1578 * for (t = terminal_list; t; t = t->next_terminal)
1579 * clear_image_cache (t, filter); */
1580 Lisp_Object tail
, frame
;
1581 FOR_EACH_FRAME (tail
, frame
)
1582 if (FRAME_WINDOW_P (XFRAME (frame
)))
1583 clear_image_cache (XFRAME (frame
), filter
);
1586 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
1588 doc
: /* Clear the image cache.
1589 FILTER nil or a frame means clear all images in the selected frame.
1590 FILTER t means clear the image caches of all frames.
1591 Anything else, means only clear those images which refer to FILTER,
1592 which is then usually a filename. */)
1593 (Lisp_Object filter
)
1595 if (!(EQ (filter
, Qnil
) || FRAMEP (filter
)))
1596 clear_image_caches (filter
);
1598 clear_image_cache (check_x_frame (filter
), Qt
);
1604 DEFUN ("image-flush", Fimage_flush
, Simage_flush
,
1606 doc
: /* Fush the image with specification SPEC on frame FRAME.
1607 This removes the image from the Emacs image cache. If SPEC specifies
1608 an image file, the next redisplay of this image will read from the
1609 current contents of that file.
1611 FRAME nil or omitted means use the selected frame.
1612 FRAME t means refresh the image on all frames. */)
1613 (Lisp_Object spec
, Lisp_Object frame
)
1615 if (!valid_image_p (spec
))
1616 error ("Invalid image specification");
1621 FOR_EACH_FRAME (tail
, frame
)
1623 struct frame
*f
= XFRAME (frame
);
1624 if (FRAME_WINDOW_P (f
))
1625 uncache_image (f
, spec
);
1629 uncache_image (check_x_frame (frame
), spec
);
1635 /* Compute masks and transform image IMG on frame F, as specified
1636 by the image's specification, */
1639 postprocess_image (struct frame
*f
, struct image
*img
)
1641 /* Manipulation of the image's mask. */
1644 Lisp_Object conversion
, spec
;
1649 /* `:heuristic-mask t'
1651 means build a mask heuristically.
1652 `:heuristic-mask (R G B)'
1653 `:mask (heuristic (R G B))'
1654 means build a mask from color (R G B) in the
1657 means remove a mask, if any. */
1659 mask
= image_spec_value (spec
, QCheuristic_mask
, NULL
);
1661 x_build_heuristic_mask (f
, img
, mask
);
1666 mask
= image_spec_value (spec
, QCmask
, &found_p
);
1668 if (EQ (mask
, Qheuristic
))
1669 x_build_heuristic_mask (f
, img
, Qt
);
1670 else if (CONSP (mask
)
1671 && EQ (XCAR (mask
), Qheuristic
))
1673 if (CONSP (XCDR (mask
)))
1674 x_build_heuristic_mask (f
, img
, XCAR (XCDR (mask
)));
1676 x_build_heuristic_mask (f
, img
, XCDR (mask
));
1678 else if (NILP (mask
) && found_p
&& img
->mask
)
1680 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
1681 img
->mask
= NO_PIXMAP
;
1686 /* Should we apply an image transformation algorithm? */
1687 conversion
= image_spec_value (spec
, QCconversion
, NULL
);
1688 if (EQ (conversion
, Qdisabled
))
1689 x_disable_image (f
, img
);
1690 else if (EQ (conversion
, Qlaplace
))
1692 else if (EQ (conversion
, Qemboss
))
1694 else if (CONSP (conversion
)
1695 && EQ (XCAR (conversion
), Qedge_detection
))
1698 tem
= XCDR (conversion
);
1700 x_edge_detection (f
, img
,
1701 Fplist_get (tem
, QCmatrix
),
1702 Fplist_get (tem
, QCcolor_adjustment
));
1708 /* Return the id of image with Lisp specification SPEC on frame F.
1709 SPEC must be a valid Lisp image specification (see valid_image_p). */
1712 lookup_image (struct frame
*f
, Lisp_Object spec
)
1718 /* F must be a window-system frame, and SPEC must be a valid image
1720 xassert (FRAME_WINDOW_P (f
));
1721 xassert (valid_image_p (spec
));
1723 /* Look up SPEC in the hash table of the image cache. */
1724 hash
= sxhash (spec
, 0);
1725 img
= search_image_cache (f
, spec
, hash
);
1726 if (img
&& img
->load_failed_p
)
1728 free_image (f
, img
);
1732 /* If not found, create a new image and cache it. */
1736 img
= make_image (spec
, hash
);
1737 cache_image (f
, img
);
1738 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
1739 img
->frame_foreground
= FRAME_FOREGROUND_PIXEL (f
);
1740 img
->frame_background
= FRAME_BACKGROUND_PIXEL (f
);
1742 /* If we can't load the image, and we don't have a width and
1743 height, use some arbitrary width and height so that we can
1744 draw a rectangle for it. */
1745 if (img
->load_failed_p
)
1749 value
= image_spec_value (spec
, QCwidth
, NULL
);
1750 img
->width
= (INTEGERP (value
)
1751 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
1752 value
= image_spec_value (spec
, QCheight
, NULL
);
1753 img
->height
= (INTEGERP (value
)
1754 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
1758 /* Handle image type independent image attributes
1759 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
1760 `:background COLOR'. */
1761 Lisp_Object ascent
, margin
, relief
, bg
;
1763 ascent
= image_spec_value (spec
, QCascent
, NULL
);
1764 if (INTEGERP (ascent
))
1765 img
->ascent
= XFASTINT (ascent
);
1766 else if (EQ (ascent
, Qcenter
))
1767 img
->ascent
= CENTERED_IMAGE_ASCENT
;
1769 margin
= image_spec_value (spec
, QCmargin
, NULL
);
1770 if (INTEGERP (margin
) && XINT (margin
) >= 0)
1771 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
1772 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
1773 && INTEGERP (XCDR (margin
)))
1775 if (XINT (XCAR (margin
)) > 0)
1776 img
->hmargin
= XFASTINT (XCAR (margin
));
1777 if (XINT (XCDR (margin
)) > 0)
1778 img
->vmargin
= XFASTINT (XCDR (margin
));
1781 relief
= image_spec_value (spec
, QCrelief
, NULL
);
1782 if (INTEGERP (relief
))
1784 img
->relief
= XINT (relief
);
1785 img
->hmargin
+= eabs (img
->relief
);
1786 img
->vmargin
+= eabs (img
->relief
);
1789 if (! img
->background_valid
)
1791 bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
1795 = x_alloc_image_color (f
, img
, bg
,
1796 FRAME_BACKGROUND_PIXEL (f
));
1797 img
->background_valid
= 1;
1801 /* Do image transformations and compute masks, unless we
1802 don't have the image yet. */
1803 if (!EQ (*img
->type
->type
, Qpostscript
))
1804 postprocess_image (f
, img
);
1810 /* We're using IMG, so set its timestamp to `now'. */
1811 EMACS_GET_TIME (now
);
1812 img
->timestamp
= EMACS_SECS (now
);
1814 /* Value is the image id. */
1819 /* Cache image IMG in the image cache of frame F. */
1822 cache_image (struct frame
*f
, struct image
*img
)
1824 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1827 /* Find a free slot in c->images. */
1828 for (i
= 0; i
< c
->used
; ++i
)
1829 if (c
->images
[i
] == NULL
)
1832 /* If no free slot found, maybe enlarge c->images. */
1833 if (i
== c
->used
&& c
->used
== c
->size
)
1836 c
->images
= (struct image
**) xrealloc (c
->images
,
1837 c
->size
* sizeof *c
->images
);
1840 /* Add IMG to c->images, and assign IMG an id. */
1846 /* Add IMG to the cache's hash table. */
1847 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1848 img
->next
= c
->buckets
[i
];
1850 img
->next
->prev
= img
;
1852 c
->buckets
[i
] = img
;
1856 /* Call FN on every image in the image cache of frame F. Used to mark
1857 Lisp Objects in the image cache. */
1859 /* Mark Lisp objects in image IMG. */
1862 mark_image (struct image
*img
)
1864 mark_object (img
->spec
);
1865 mark_object (img
->dependencies
);
1867 if (!NILP (img
->lisp_data
))
1868 mark_object (img
->lisp_data
);
1873 mark_image_cache (struct image_cache
*c
)
1878 for (i
= 0; i
< c
->used
; ++i
)
1880 mark_image (c
->images
[i
]);
1886 /***********************************************************************
1887 X / NS / W32 support code
1888 ***********************************************************************/
1892 /* Macro for defining functions that will be loaded from image DLLs. */
1893 #define DEF_IMGLIB_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args
1895 /* Macro for loading those image functions from the library. */
1896 #define LOAD_IMGLIB_FN(lib,func) { \
1897 fn_##func = (void *) GetProcAddress (lib, #func); \
1898 if (!fn_##func) return 0; \
1901 #endif /* HAVE_NTGUI */
1903 static int x_create_x_image_and_pixmap (struct frame
*, int, int, int,
1904 XImagePtr
*, Pixmap
*);
1905 static void x_destroy_x_image (XImagePtr
);
1906 static void x_put_x_image (struct frame
*, XImagePtr
, Pixmap
, int, int);
1909 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
1910 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
1911 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
1912 via xmalloc. Print error messages via image_error if an error
1913 occurs. Value is non-zero if successful.
1915 On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
1916 should indicate the bit depth of the image. */
1919 x_create_x_image_and_pixmap (struct frame
*f
, int width
, int height
, int depth
,
1920 XImagePtr
*ximg
, Pixmap
*pixmap
)
1922 #ifdef HAVE_X_WINDOWS
1923 Display
*display
= FRAME_X_DISPLAY (f
);
1924 Window window
= FRAME_X_WINDOW (f
);
1925 Screen
*screen
= FRAME_X_SCREEN (f
);
1927 xassert (interrupt_input_blocked
);
1930 depth
= DefaultDepthOfScreen (screen
);
1931 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
1932 depth
, ZPixmap
, 0, NULL
, width
, height
,
1933 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
1936 image_error ("Unable to allocate X image", Qnil
, Qnil
);
1940 /* Allocate image raster. */
1941 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
1943 /* Allocate a pixmap of the same size. */
1944 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
1945 if (*pixmap
== NO_PIXMAP
)
1947 x_destroy_x_image (*ximg
);
1949 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
1954 #endif /* HAVE_X_WINDOWS */
1958 BITMAPINFOHEADER
*header
;
1960 int scanline_width_bits
;
1962 int palette_colors
= 0;
1967 if (depth
!= 1 && depth
!= 4 && depth
!= 8
1968 && depth
!= 16 && depth
!= 24 && depth
!= 32)
1970 image_error ("Invalid image bit depth specified", Qnil
, Qnil
);
1974 scanline_width_bits
= width
* depth
;
1975 remainder
= scanline_width_bits
% 32;
1978 scanline_width_bits
+= 32 - remainder
;
1980 /* Bitmaps with a depth less than 16 need a palette. */
1981 /* BITMAPINFO structure already contains the first RGBQUAD. */
1983 palette_colors
= 1 << depth
- 1;
1985 *ximg
= xmalloc (sizeof (XImage
) + palette_colors
* sizeof (RGBQUAD
));
1988 image_error ("Unable to allocate memory for XImage", Qnil
, Qnil
);
1992 header
= &(*ximg
)->info
.bmiHeader
;
1993 memset (&(*ximg
)->info
, 0, sizeof (BITMAPINFO
));
1994 header
->biSize
= sizeof (*header
);
1995 header
->biWidth
= width
;
1996 header
->biHeight
= -height
; /* negative indicates a top-down bitmap. */
1997 header
->biPlanes
= 1;
1998 header
->biBitCount
= depth
;
1999 header
->biCompression
= BI_RGB
;
2000 header
->biClrUsed
= palette_colors
;
2002 /* TODO: fill in palette. */
2005 (*ximg
)->info
.bmiColors
[0].rgbBlue
= 0;
2006 (*ximg
)->info
.bmiColors
[0].rgbGreen
= 0;
2007 (*ximg
)->info
.bmiColors
[0].rgbRed
= 0;
2008 (*ximg
)->info
.bmiColors
[0].rgbReserved
= 0;
2009 (*ximg
)->info
.bmiColors
[1].rgbBlue
= 255;
2010 (*ximg
)->info
.bmiColors
[1].rgbGreen
= 255;
2011 (*ximg
)->info
.bmiColors
[1].rgbRed
= 255;
2012 (*ximg
)->info
.bmiColors
[1].rgbReserved
= 0;
2015 hdc
= get_frame_dc (f
);
2017 /* Create a DIBSection and raster array for the bitmap,
2018 and store its handle in *pixmap. */
2019 *pixmap
= CreateDIBSection (hdc
, &((*ximg
)->info
),
2020 (depth
< 16) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
,
2021 /* casting avoids a GCC warning */
2022 (void **)&((*ximg
)->data
), NULL
, 0);
2024 /* Realize display palette and garbage all frames. */
2025 release_frame_dc (f
, hdc
);
2027 if (*pixmap
== NULL
)
2029 DWORD err
= GetLastError ();
2030 Lisp_Object errcode
;
2031 /* All system errors are < 10000, so the following is safe. */
2032 XSETINT (errcode
, (int) err
);
2033 image_error ("Unable to create bitmap, error code %d", errcode
, Qnil
);
2034 x_destroy_x_image (*ximg
);
2040 #endif /* HAVE_NTGUI */
2043 *pixmap
= ns_image_for_XPM (width
, height
, depth
);
2047 image_error ("Unable to allocate NSImage for XPM pixmap", Qnil
, Qnil
);
2056 /* Destroy XImage XIMG. Free XIMG->data. */
2059 x_destroy_x_image (XImagePtr ximg
)
2061 xassert (interrupt_input_blocked
);
2064 #ifdef HAVE_X_WINDOWS
2067 XDestroyImage (ximg
);
2068 #endif /* HAVE_X_WINDOWS */
2070 /* Data will be freed by DestroyObject. */
2073 #endif /* HAVE_NTGUI */
2075 ns_release_object (ximg
);
2076 #endif /* HAVE_NS */
2081 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
2082 are width and height of both the image and pixmap. */
2085 x_put_x_image (struct frame
*f
, XImagePtr ximg
, Pixmap pixmap
, int width
, int height
)
2087 #ifdef HAVE_X_WINDOWS
2090 xassert (interrupt_input_blocked
);
2091 gc
= XCreateGC (FRAME_X_DISPLAY (f
), pixmap
, 0, NULL
);
2092 XPutImage (FRAME_X_DISPLAY (f
), pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
2093 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
2094 #endif /* HAVE_X_WINDOWS */
2097 #if 0 /* I don't think this is necessary looking at where it is used. */
2098 HDC hdc
= get_frame_dc (f
);
2099 SetDIBits (hdc
, pixmap
, 0, height
, ximg
->data
, &(ximg
->info
), DIB_RGB_COLORS
);
2100 release_frame_dc (f
, hdc
);
2102 #endif /* HAVE_NTGUI */
2105 xassert (ximg
== pixmap
);
2106 ns_retain_object (ximg
);
2111 /***********************************************************************
2113 ***********************************************************************/
2115 /* Find image file FILE. Look in data-directory/images, then
2116 x-bitmap-file-path. Value is the encoded full name of the file
2117 found, or nil if not found. */
2120 x_find_image_file (Lisp_Object file
)
2122 Lisp_Object file_found
, search_path
;
2125 /* TODO I think this should use something like image-load-path
2126 instead. Unfortunately, that can contain non-string elements. */
2127 search_path
= Fcons (Fexpand_file_name (build_string ("images"),
2129 Vx_bitmap_file_path
);
2131 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
2132 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
2138 file_found
= ENCODE_FILE (file_found
);
2146 /* Read FILE into memory. Value is a pointer to a buffer allocated
2147 with xmalloc holding FILE's contents. Value is null if an error
2148 occurred. *SIZE is set to the size of the file. */
2150 static unsigned char *
2151 slurp_file (char *file
, ptrdiff_t *size
)
2154 unsigned char *buf
= NULL
;
2157 if (stat (file
, &st
) == 0
2158 && (fp
= fopen (file
, "rb")) != NULL
2159 && 0 <= st
.st_size
&& st
.st_size
<= min (PTRDIFF_MAX
, SIZE_MAX
)
2160 && (buf
= (unsigned char *) xmalloc (st
.st_size
),
2161 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
2182 /***********************************************************************
2184 ***********************************************************************/
2186 static int xbm_scan (unsigned char **, unsigned char *, char *, int *);
2187 static int xbm_load (struct frame
*f
, struct image
*img
);
2188 static int xbm_load_image (struct frame
*f
, struct image
*img
,
2189 unsigned char *, unsigned char *);
2190 static int xbm_image_p (Lisp_Object object
);
2191 static int xbm_read_bitmap_data (struct frame
*f
,
2192 unsigned char *, unsigned char *,
2193 int *, int *, char **, int);
2194 static int xbm_file_p (Lisp_Object
);
2197 /* Indices of image specification fields in xbm_format, below. */
2199 enum xbm_keyword_index
2217 /* Vector of image_keyword structures describing the format
2218 of valid XBM image specifications. */
2220 static const struct image_keyword xbm_format
[XBM_LAST
] =
2222 {":type", IMAGE_SYMBOL_VALUE
, 1},
2223 {":file", IMAGE_STRING_VALUE
, 0},
2224 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2225 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2226 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2227 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
2228 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
2229 {":ascent", IMAGE_ASCENT_VALUE
, 0},
2230 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
2231 {":relief", IMAGE_INTEGER_VALUE
, 0},
2232 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2233 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2234 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
2237 /* Structure describing the image type XBM. */
2239 static struct image_type xbm_type
=
2248 /* Tokens returned from xbm_scan. */
2257 /* Return non-zero if OBJECT is a valid XBM-type image specification.
2258 A valid specification is a list starting with the symbol `image'
2259 The rest of the list is a property list which must contain an
2262 If the specification specifies a file to load, it must contain
2263 an entry `:file FILENAME' where FILENAME is a string.
2265 If the specification is for a bitmap loaded from memory it must
2266 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
2267 WIDTH and HEIGHT are integers > 0. DATA may be:
2269 1. a string large enough to hold the bitmap data, i.e. it must
2270 have a size >= (WIDTH + 7) / 8 * HEIGHT
2272 2. a bool-vector of size >= WIDTH * HEIGHT
2274 3. a vector of strings or bool-vectors, one for each line of the
2277 4. a string containing an in-memory XBM file. WIDTH and HEIGHT
2278 may not be specified in this case because they are defined in the
2281 Both the file and data forms may contain the additional entries
2282 `:background COLOR' and `:foreground COLOR'. If not present,
2283 foreground and background of the frame on which the image is
2284 displayed is used. */
2287 xbm_image_p (Lisp_Object object
)
2289 struct image_keyword kw
[XBM_LAST
];
2291 memcpy (kw
, xbm_format
, sizeof kw
);
2292 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
2295 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
2297 if (kw
[XBM_FILE
].count
)
2299 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
2302 else if (kw
[XBM_DATA
].count
&& xbm_file_p (kw
[XBM_DATA
].value
))
2304 /* In-memory XBM file. */
2305 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_FILE
].count
)
2313 /* Entries for `:width', `:height' and `:data' must be present. */
2314 if (!kw
[XBM_WIDTH
].count
2315 || !kw
[XBM_HEIGHT
].count
2316 || !kw
[XBM_DATA
].count
)
2319 data
= kw
[XBM_DATA
].value
;
2320 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
2321 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
2323 /* Check type of data, and width and height against contents of
2329 /* Number of elements of the vector must be >= height. */
2330 if (ASIZE (data
) < height
)
2333 /* Each string or bool-vector in data must be large enough
2334 for one line of the image. */
2335 for (i
= 0; i
< height
; ++i
)
2337 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
2342 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
2345 else if (BOOL_VECTOR_P (elt
))
2347 if (XBOOL_VECTOR (elt
)->size
< width
)
2354 else if (STRINGP (data
))
2357 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
2360 else if (BOOL_VECTOR_P (data
))
2362 if (XBOOL_VECTOR (data
)->size
< width
* height
)
2373 /* Scan a bitmap file. FP is the stream to read from. Value is
2374 either an enumerator from enum xbm_token, or a character for a
2375 single-character token, or 0 at end of file. If scanning an
2376 identifier, store the lexeme of the identifier in SVAL. If
2377 scanning a number, store its value in *IVAL. */
2380 xbm_scan (unsigned char **s
, unsigned char *end
, char *sval
, int *ival
)
2386 /* Skip white space. */
2387 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
2392 else if (isdigit (c
))
2394 int value
= 0, digit
;
2396 if (c
== '0' && *s
< end
)
2399 if (c
== 'x' || c
== 'X')
2406 else if (c
>= 'a' && c
<= 'f')
2407 digit
= c
- 'a' + 10;
2408 else if (c
>= 'A' && c
<= 'F')
2409 digit
= c
- 'A' + 10;
2412 value
= 16 * value
+ digit
;
2415 else if (isdigit (c
))
2419 && (c
= *(*s
)++, isdigit (c
)))
2420 value
= 8 * value
+ c
- '0';
2427 && (c
= *(*s
)++, isdigit (c
)))
2428 value
= 10 * value
+ c
- '0';
2436 else if (isalpha (c
) || c
== '_')
2440 && (c
= *(*s
)++, (isalnum (c
) || c
== '_')))
2447 else if (c
== '/' && **s
== '*')
2449 /* C-style comment. */
2451 while (**s
&& (**s
!= '*' || *(*s
+ 1) != '/'))
2465 /* Create a Windows bitmap from X bitmap data. */
2467 w32_create_pixmap_from_bitmap_data (int width
, int height
, char *data
)
2469 static unsigned char swap_nibble
[16]
2470 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
2471 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
2472 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
2473 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
2475 unsigned char *bits
, *p
;
2478 w1
= (width
+ 7) / 8; /* nb of 8bits elt in X bitmap */
2479 w2
= ((width
+ 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
2480 bits
= (unsigned char *) alloca (height
* w2
);
2481 memset (bits
, 0, height
* w2
);
2482 for (i
= 0; i
< height
; i
++)
2485 for (j
= 0; j
< w1
; j
++)
2487 /* Bitswap XBM bytes to match how Windows does things. */
2488 unsigned char c
= *data
++;
2489 *p
++ = (unsigned char)((swap_nibble
[c
& 0xf] << 4)
2490 | (swap_nibble
[(c
>>4) & 0xf]));
2493 bmp
= CreateBitmap (width
, height
, 1, 1, (char *) bits
);
2499 convert_mono_to_color_image (struct frame
*f
, struct image
*img
,
2500 COLORREF foreground
, COLORREF background
)
2502 HDC hdc
, old_img_dc
, new_img_dc
;
2503 HGDIOBJ old_prev
, new_prev
;
2506 hdc
= get_frame_dc (f
);
2507 old_img_dc
= CreateCompatibleDC (hdc
);
2508 new_img_dc
= CreateCompatibleDC (hdc
);
2509 new_pixmap
= CreateCompatibleBitmap (hdc
, img
->width
, img
->height
);
2510 release_frame_dc (f
, hdc
);
2511 old_prev
= SelectObject (old_img_dc
, img
->pixmap
);
2512 new_prev
= SelectObject (new_img_dc
, new_pixmap
);
2513 /* Windows convention for mono bitmaps is black = background,
2514 white = foreground. */
2515 SetTextColor (new_img_dc
, background
);
2516 SetBkColor (new_img_dc
, foreground
);
2518 BitBlt (new_img_dc
, 0, 0, img
->width
, img
->height
, old_img_dc
,
2521 SelectObject (old_img_dc
, old_prev
);
2522 SelectObject (new_img_dc
, new_prev
);
2523 DeleteDC (old_img_dc
);
2524 DeleteDC (new_img_dc
);
2525 DeleteObject (img
->pixmap
);
2526 if (new_pixmap
== 0)
2527 fprintf (stderr
, "Failed to convert image to color.\n");
2529 img
->pixmap
= new_pixmap
;
2532 #define XBM_BIT_SHUFFLE(b) (~(b))
2536 #define XBM_BIT_SHUFFLE(b) (b)
2538 #endif /* HAVE_NTGUI */
2542 Create_Pixmap_From_Bitmap_Data (struct frame
*f
, struct image
*img
, char *data
,
2543 RGB_PIXEL_COLOR fg
, RGB_PIXEL_COLOR bg
,
2544 int non_default_colors
)
2548 = w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
, data
);
2550 /* If colors were specified, transfer the bitmap to a color one. */
2551 if (non_default_colors
)
2552 convert_mono_to_color_image (f
, img
, fg
, bg
);
2554 #elif defined (HAVE_NS)
2555 img
->pixmap
= ns_image_from_XBM (data
, img
->width
, img
->height
);
2559 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
2562 img
->width
, img
->height
,
2564 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
2565 #endif /* !HAVE_NTGUI && !HAVE_NS */
2570 /* Replacement for XReadBitmapFileData which isn't available under old
2571 X versions. CONTENTS is a pointer to a buffer to parse; END is the
2572 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
2573 the image. Return in *DATA the bitmap data allocated with xmalloc.
2574 Value is non-zero if successful. DATA null means just test if
2575 CONTENTS looks like an in-memory XBM file. If INHIBIT_IMAGE_ERROR
2576 is non-zero, inhibit the call to image_error when the image size is
2577 invalid (the bitmap remains unread). */
2580 xbm_read_bitmap_data (struct frame
*f
, unsigned char *contents
, unsigned char *end
,
2581 int *width
, int *height
, char **data
,
2582 int inhibit_image_error
)
2584 unsigned char *s
= contents
;
2585 char buffer
[BUFSIZ
];
2588 int bytes_per_line
, i
, nbytes
;
2594 LA1 = xbm_scan (&s, end, buffer, &value)
2596 #define expect(TOKEN) \
2597 if (LA1 != (TOKEN)) \
2602 #define expect_ident(IDENT) \
2603 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
2608 *width
= *height
= -1;
2611 LA1
= xbm_scan (&s
, end
, buffer
, &value
);
2613 /* Parse defines for width, height and hot-spots. */
2617 expect_ident ("define");
2618 expect (XBM_TK_IDENT
);
2620 if (LA1
== XBM_TK_NUMBER
)
2622 char *q
= strrchr (buffer
, '_');
2623 q
= q
? q
+ 1 : buffer
;
2624 if (strcmp (q
, "width") == 0)
2626 else if (strcmp (q
, "height") == 0)
2629 expect (XBM_TK_NUMBER
);
2632 if (!check_image_size (f
, *width
, *height
))
2634 if (!inhibit_image_error
)
2635 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
2638 else if (data
== NULL
)
2641 /* Parse bits. Must start with `static'. */
2642 expect_ident ("static");
2643 if (LA1
== XBM_TK_IDENT
)
2645 if (strcmp (buffer
, "unsigned") == 0)
2648 expect_ident ("char");
2650 else if (strcmp (buffer
, "short") == 0)
2654 if (*width
% 16 && *width
% 16 < 9)
2657 else if (strcmp (buffer
, "char") == 0)
2665 expect (XBM_TK_IDENT
);
2671 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
2672 nbytes
= bytes_per_line
* *height
;
2673 p
= *data
= (char *) xmalloc (nbytes
);
2677 for (i
= 0; i
< nbytes
; i
+= 2)
2680 expect (XBM_TK_NUMBER
);
2682 *p
++ = XBM_BIT_SHUFFLE (val
);
2683 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
2684 *p
++ = XBM_BIT_SHUFFLE (value
>> 8);
2686 if (LA1
== ',' || LA1
== '}')
2694 for (i
= 0; i
< nbytes
; ++i
)
2697 expect (XBM_TK_NUMBER
);
2699 *p
++ = XBM_BIT_SHUFFLE (val
);
2701 if (LA1
== ',' || LA1
== '}')
2726 /* Load XBM image IMG which will be displayed on frame F from buffer
2727 CONTENTS. END is the end of the buffer. Value is non-zero if
2731 xbm_load_image (struct frame
*f
, struct image
*img
, unsigned char *contents
,
2738 rc
= xbm_read_bitmap_data (f
, contents
, end
, &img
->width
, &img
->height
,
2742 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2743 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2744 int non_default_colors
= 0;
2747 xassert (img
->width
> 0 && img
->height
> 0);
2749 /* Get foreground and background colors, maybe allocate colors. */
2750 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
2753 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
2754 non_default_colors
= 1;
2756 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
2759 background
= x_alloc_image_color (f
, img
, value
, background
);
2760 img
->background
= background
;
2761 img
->background_valid
= 1;
2762 non_default_colors
= 1;
2765 Create_Pixmap_From_Bitmap_Data (f
, img
, data
,
2766 foreground
, background
,
2767 non_default_colors
);
2770 if (img
->pixmap
== NO_PIXMAP
)
2772 x_clear_image (f
, img
);
2773 image_error ("Unable to create X pixmap for `%s'", img
->spec
, Qnil
);
2779 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
2785 /* Value is non-zero if DATA looks like an in-memory XBM file. */
2788 xbm_file_p (Lisp_Object data
)
2791 return (STRINGP (data
)
2792 && xbm_read_bitmap_data (NULL
, SDATA (data
),
2793 (SDATA (data
) + SBYTES (data
)),
2798 /* Fill image IMG which is used on frame F with pixmap data. Value is
2799 non-zero if successful. */
2802 xbm_load (struct frame
*f
, struct image
*img
)
2805 Lisp_Object file_name
;
2807 xassert (xbm_image_p (img
->spec
));
2809 /* If IMG->spec specifies a file name, create a non-file spec from it. */
2810 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
2811 if (STRINGP (file_name
))
2814 unsigned char *contents
;
2817 file
= x_find_image_file (file_name
);
2818 if (!STRINGP (file
))
2820 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
2824 contents
= slurp_file (SSDATA (file
), &size
);
2825 if (contents
== NULL
)
2827 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
2831 success_p
= xbm_load_image (f
, img
, contents
, contents
+ size
);
2835 struct image_keyword fmt
[XBM_LAST
];
2837 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2838 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2839 int non_default_colors
= 0;
2842 int in_memory_file_p
= 0;
2844 /* See if data looks like an in-memory XBM file. */
2845 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
2846 in_memory_file_p
= xbm_file_p (data
);
2848 /* Parse the image specification. */
2849 memcpy (fmt
, xbm_format
, sizeof fmt
);
2850 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
2854 /* Get specified width, and height. */
2855 if (!in_memory_file_p
)
2857 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
2858 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
2859 xassert (img
->width
> 0 && img
->height
> 0);
2862 /* Get foreground and background colors, maybe allocate colors. */
2863 if (fmt
[XBM_FOREGROUND
].count
2864 && STRINGP (fmt
[XBM_FOREGROUND
].value
))
2866 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
2868 non_default_colors
= 1;
2871 if (fmt
[XBM_BACKGROUND
].count
2872 && STRINGP (fmt
[XBM_BACKGROUND
].value
))
2874 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
2876 non_default_colors
= 1;
2879 if (in_memory_file_p
)
2880 success_p
= xbm_load_image (f
, img
, SDATA (data
),
2889 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
2891 p
= bits
= (char *) alloca (nbytes
* img
->height
);
2892 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
2894 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
2896 memcpy (p
, SDATA (line
), nbytes
);
2898 memcpy (p
, XBOOL_VECTOR (line
)->data
, nbytes
);
2901 else if (STRINGP (data
))
2902 bits
= SSDATA (data
);
2904 bits
= (char *) XBOOL_VECTOR (data
)->data
;
2910 /* Windows mono bitmaps are reversed compared with X. */
2911 invertedBits
= bits
;
2912 nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
2914 bits
= (char *) alloca (nbytes
);
2915 for (i
= 0; i
< nbytes
; i
++)
2916 bits
[i
] = XBM_BIT_SHUFFLE (invertedBits
[i
]);
2919 /* Create the pixmap. */
2921 Create_Pixmap_From_Bitmap_Data (f
, img
, bits
,
2922 foreground
, background
,
2923 non_default_colors
);
2928 image_error ("Unable to create pixmap for XBM image `%s'",
2930 x_clear_image (f
, img
);
2940 /***********************************************************************
2942 ***********************************************************************/
2944 #if defined (HAVE_XPM) || defined (HAVE_NS)
2946 static int xpm_image_p (Lisp_Object object
);
2947 static int xpm_load (struct frame
*f
, struct image
*img
);
2948 static int xpm_valid_color_symbols_p (Lisp_Object
);
2950 #endif /* HAVE_XPM || HAVE_NS */
2954 /* Indicate to xpm.h that we don't have Xlib. */
2956 /* simx.h in xpm defines XColor and XImage differently than Emacs. */
2957 /* It also defines Display the same way as Emacs, but gcc 3.3 still barfs. */
2958 #define XColor xpm_XColor
2959 #define XImage xpm_XImage
2960 #define Display xpm_Display
2961 #define PIXEL_ALREADY_TYPEDEFED
2962 #include "X11/xpm.h"
2967 #undef PIXEL_ALREADY_TYPEDEFED
2969 #include "X11/xpm.h"
2970 #endif /* HAVE_NTGUI */
2971 #endif /* HAVE_XPM */
2973 #if defined (HAVE_XPM) || defined (HAVE_NS)
2974 /* The symbol `xpm' identifying XPM-format images. */
2976 static Lisp_Object Qxpm
;
2978 /* Indices of image specification fields in xpm_format, below. */
2980 enum xpm_keyword_index
2996 /* Vector of image_keyword structures describing the format
2997 of valid XPM image specifications. */
2999 static const struct image_keyword xpm_format
[XPM_LAST
] =
3001 {":type", IMAGE_SYMBOL_VALUE
, 1},
3002 {":file", IMAGE_STRING_VALUE
, 0},
3003 {":data", IMAGE_STRING_VALUE
, 0},
3004 {":ascent", IMAGE_ASCENT_VALUE
, 0},
3005 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
3006 {":relief", IMAGE_INTEGER_VALUE
, 0},
3007 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3008 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3009 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3010 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3011 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
3014 /* Structure describing the image type XPM. */
3016 static struct image_type xpm_type
=
3025 #ifdef HAVE_X_WINDOWS
3027 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
3028 functions for allocating image colors. Our own functions handle
3029 color allocation failures more gracefully than the ones on the XPM
3032 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
3033 #define ALLOC_XPM_COLORS
3035 #endif /* HAVE_X_WINDOWS */
3037 #ifdef ALLOC_XPM_COLORS
3039 static void xpm_init_color_cache (struct frame
*, XpmAttributes
*);
3040 static void xpm_free_color_cache (void);
3041 static int xpm_lookup_color (struct frame
*, char *, XColor
*);
3042 static int xpm_color_bucket (char *);
3043 static struct xpm_cached_color
*xpm_cache_color (struct frame
*, char *,
3046 /* An entry in a hash table used to cache color definitions of named
3047 colors. This cache is necessary to speed up XPM image loading in
3048 case we do color allocations ourselves. Without it, we would need
3049 a call to XParseColor per pixel in the image. */
3051 struct xpm_cached_color
3053 /* Next in collision chain. */
3054 struct xpm_cached_color
*next
;
3056 /* Color definition (RGB and pixel color). */
3063 /* The hash table used for the color cache, and its bucket vector
3066 #define XPM_COLOR_CACHE_BUCKETS 1001
3067 static struct xpm_cached_color
**xpm_color_cache
;
3069 /* Initialize the color cache. */
3072 xpm_init_color_cache (struct frame
*f
, XpmAttributes
*attrs
)
3074 size_t nbytes
= XPM_COLOR_CACHE_BUCKETS
* sizeof *xpm_color_cache
;
3075 xpm_color_cache
= (struct xpm_cached_color
**) xmalloc (nbytes
);
3076 memset (xpm_color_cache
, 0, nbytes
);
3077 init_color_table ();
3079 if (attrs
->valuemask
& XpmColorSymbols
)
3084 for (i
= 0; i
< attrs
->numsymbols
; ++i
)
3085 if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
3086 attrs
->colorsymbols
[i
].value
, &color
))
3088 color
.pixel
= lookup_rgb_color (f
, color
.red
, color
.green
,
3090 xpm_cache_color (f
, attrs
->colorsymbols
[i
].name
, &color
, -1);
3095 /* Free the color cache. */
3098 xpm_free_color_cache (void)
3100 struct xpm_cached_color
*p
, *next
;
3103 for (i
= 0; i
< XPM_COLOR_CACHE_BUCKETS
; ++i
)
3104 for (p
= xpm_color_cache
[i
]; p
; p
= next
)
3110 xfree (xpm_color_cache
);
3111 xpm_color_cache
= NULL
;
3112 free_color_table ();
3115 /* Return the bucket index for color named COLOR_NAME in the color
3119 xpm_color_bucket (char *color_name
)
3124 for (s
= color_name
; *s
; ++s
)
3126 return h
%= XPM_COLOR_CACHE_BUCKETS
;
3130 /* On frame F, cache values COLOR for color with name COLOR_NAME.
3131 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
3134 static struct xpm_cached_color
*
3135 xpm_cache_color (struct frame
*f
, char *color_name
, XColor
*color
, int bucket
)
3138 struct xpm_cached_color
*p
;
3141 bucket
= xpm_color_bucket (color_name
);
3143 nbytes
= sizeof *p
+ strlen (color_name
);
3144 p
= (struct xpm_cached_color
*) xmalloc (nbytes
);
3145 strcpy (p
->name
, color_name
);
3147 p
->next
= xpm_color_cache
[bucket
];
3148 xpm_color_cache
[bucket
] = p
;
3152 /* Look up color COLOR_NAME for frame F in the color cache. If found,
3153 return the cached definition in *COLOR. Otherwise, make a new
3154 entry in the cache and allocate the color. Value is zero if color
3155 allocation failed. */
3158 xpm_lookup_color (struct frame
*f
, char *color_name
, XColor
*color
)
3160 struct xpm_cached_color
*p
;
3161 int h
= xpm_color_bucket (color_name
);
3163 for (p
= xpm_color_cache
[h
]; p
; p
= p
->next
)
3164 if (strcmp (p
->name
, color_name
) == 0)
3169 else if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
3172 color
->pixel
= lookup_rgb_color (f
, color
->red
, color
->green
,
3174 p
= xpm_cache_color (f
, color_name
, color
, h
);
3176 /* You get `opaque' at least from ImageMagick converting pbm to xpm
3177 with transparency, and it's useful. */
3178 else if (strcmp ("opaque", color_name
) == 0)
3180 memset (color
, 0, sizeof (XColor
)); /* Is this necessary/correct? */
3181 color
->pixel
= FRAME_FOREGROUND_PIXEL (f
);
3182 p
= xpm_cache_color (f
, color_name
, color
, h
);
3189 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
3190 CLOSURE is a pointer to the frame on which we allocate the
3191 color. Return in *COLOR the allocated color. Value is non-zero
3195 xpm_alloc_color (Display
*dpy
, Colormap cmap
, char *color_name
, XColor
*color
,
3198 return xpm_lookup_color ((struct frame
*) closure
, color_name
, color
);
3202 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
3203 is a pointer to the frame on which we allocate the color. Value is
3204 non-zero if successful. */
3207 xpm_free_colors (Display
*dpy
, Colormap cmap
, Pixel
*pixels
, int npixels
, void *closure
)
3212 #endif /* ALLOC_XPM_COLORS */
3217 /* XPM library details. */
3219 DEF_IMGLIB_FN (void, XpmFreeAttributes
, (XpmAttributes
*));
3220 DEF_IMGLIB_FN (int, XpmCreateImageFromBuffer
, (Display
*, char *, xpm_XImage
**,
3221 xpm_XImage
**, XpmAttributes
*));
3222 DEF_IMGLIB_FN (int, XpmReadFileToImage
, (Display
*, char *, xpm_XImage
**,
3223 xpm_XImage
**, XpmAttributes
*));
3224 DEF_IMGLIB_FN (void, XImageFree
, (xpm_XImage
*));
3227 init_xpm_functions (Lisp_Object libraries
)
3231 if (!(library
= w32_delayed_load (libraries
, Qxpm
)))
3234 LOAD_IMGLIB_FN (library
, XpmFreeAttributes
);
3235 LOAD_IMGLIB_FN (library
, XpmCreateImageFromBuffer
);
3236 LOAD_IMGLIB_FN (library
, XpmReadFileToImage
);
3237 LOAD_IMGLIB_FN (library
, XImageFree
);
3241 #endif /* HAVE_NTGUI */
3244 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
3245 for XPM images. Such a list must consist of conses whose car and
3249 xpm_valid_color_symbols_p (Lisp_Object color_symbols
)
3251 while (CONSP (color_symbols
))
3253 Lisp_Object sym
= XCAR (color_symbols
);
3255 || !STRINGP (XCAR (sym
))
3256 || !STRINGP (XCDR (sym
)))
3258 color_symbols
= XCDR (color_symbols
);
3261 return NILP (color_symbols
);
3265 /* Value is non-zero if OBJECT is a valid XPM image specification. */
3268 xpm_image_p (Lisp_Object object
)
3270 struct image_keyword fmt
[XPM_LAST
];
3271 memcpy (fmt
, xpm_format
, sizeof fmt
);
3272 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
3273 /* Either `:file' or `:data' must be present. */
3274 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
3275 /* Either no `:color-symbols' or it's a list of conses
3276 whose car and cdr are strings. */
3277 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
3278 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
)));
3281 #endif /* HAVE_XPM || HAVE_NS */
3283 #if defined HAVE_XPM && defined HAVE_X_WINDOWS && !defined USE_GTK
3285 x_create_bitmap_from_xpm_data (struct frame
*f
, const char **bits
)
3287 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3289 XpmAttributes attrs
;
3290 Pixmap bitmap
, mask
;
3292 memset (&attrs
, 0, sizeof attrs
);
3294 attrs
.visual
= FRAME_X_VISUAL (f
);
3295 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3296 attrs
.valuemask
|= XpmVisual
;
3297 attrs
.valuemask
|= XpmColormap
;
3299 rc
= XpmCreatePixmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3300 (char **) bits
, &bitmap
, &mask
, &attrs
);
3301 if (rc
!= XpmSuccess
)
3303 XpmFreeAttributes (&attrs
);
3307 id
= x_allocate_bitmap_record (f
);
3308 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
3309 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
3310 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
3311 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
3312 dpyinfo
->bitmaps
[id
- 1].height
= attrs
.height
;
3313 dpyinfo
->bitmaps
[id
- 1].width
= attrs
.width
;
3314 dpyinfo
->bitmaps
[id
- 1].depth
= attrs
.depth
;
3315 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
3317 XpmFreeAttributes (&attrs
);
3320 #endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */
3322 /* Load image IMG which will be displayed on frame F. Value is
3323 non-zero if successful. */
3328 xpm_load (struct frame
*f
, struct image
*img
)
3331 XpmAttributes attrs
;
3332 Lisp_Object specified_file
, color_symbols
;
3335 xpm_XImage
* xpm_image
= NULL
, * xpm_mask
= NULL
;
3336 #endif /* HAVE_NTGUI */
3338 /* Configure the XPM lib. Use the visual of frame F. Allocate
3339 close colors. Return colors allocated. */
3340 memset (&attrs
, 0, sizeof attrs
);
3343 attrs
.visual
= FRAME_X_VISUAL (f
);
3344 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3345 attrs
.valuemask
|= XpmVisual
;
3346 attrs
.valuemask
|= XpmColormap
;
3347 #endif /* HAVE_NTGUI */
3349 #ifdef ALLOC_XPM_COLORS
3350 /* Allocate colors with our own functions which handle
3351 failing color allocation more gracefully. */
3352 attrs
.color_closure
= f
;
3353 attrs
.alloc_color
= xpm_alloc_color
;
3354 attrs
.free_colors
= xpm_free_colors
;
3355 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
3356 #else /* not ALLOC_XPM_COLORS */
3357 /* Let the XPM lib allocate colors. */
3358 attrs
.valuemask
|= XpmReturnAllocPixels
;
3359 #ifdef XpmAllocCloseColors
3360 attrs
.alloc_close_colors
= 1;
3361 attrs
.valuemask
|= XpmAllocCloseColors
;
3362 #else /* not XpmAllocCloseColors */
3363 attrs
.closeness
= 600;
3364 attrs
.valuemask
|= XpmCloseness
;
3365 #endif /* not XpmAllocCloseColors */
3366 #endif /* ALLOC_XPM_COLORS */
3368 /* If image specification contains symbolic color definitions, add
3369 these to `attrs'. */
3370 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
3371 if (CONSP (color_symbols
))
3374 XpmColorSymbol
*xpm_syms
;
3377 attrs
.valuemask
|= XpmColorSymbols
;
3379 /* Count number of symbols. */
3380 attrs
.numsymbols
= 0;
3381 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
3384 /* Allocate an XpmColorSymbol array. */
3385 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
3386 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
3387 memset (xpm_syms
, 0, size
);
3388 attrs
.colorsymbols
= xpm_syms
;
3390 /* Fill the color symbol array. */
3391 for (tail
= color_symbols
, i
= 0;
3393 ++i
, tail
= XCDR (tail
))
3397 char *empty_string
= (char *) "";
3399 if (!CONSP (XCAR (tail
)))
3401 xpm_syms
[i
].name
= empty_string
;
3402 xpm_syms
[i
].value
= empty_string
;
3405 name
= XCAR (XCAR (tail
));
3406 color
= XCDR (XCAR (tail
));
3409 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
3410 strcpy (xpm_syms
[i
].name
, SSDATA (name
));
3413 xpm_syms
[i
].name
= empty_string
;
3414 if (STRINGP (color
))
3416 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
3417 strcpy (xpm_syms
[i
].value
, SSDATA (color
));
3420 xpm_syms
[i
].value
= empty_string
;
3424 /* Create a pixmap for the image, either from a file, or from a
3425 string buffer containing data in the same format as an XPM file. */
3426 #ifdef ALLOC_XPM_COLORS
3427 xpm_init_color_cache (f
, &attrs
);
3430 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
3434 HDC frame_dc
= get_frame_dc (f
);
3435 hdc
= CreateCompatibleDC (frame_dc
);
3436 release_frame_dc (f
, frame_dc
);
3438 #endif /* HAVE_NTGUI */
3440 if (STRINGP (specified_file
))
3442 Lisp_Object file
= x_find_image_file (specified_file
);
3443 if (!STRINGP (file
))
3445 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
3446 #ifdef ALLOC_XPM_COLORS
3447 xpm_free_color_cache ();
3453 /* XpmReadFileToPixmap is not available in the Windows port of
3454 libxpm. But XpmReadFileToImage almost does what we want. */
3455 rc
= fn_XpmReadFileToImage (&hdc
, SDATA (file
),
3456 &xpm_image
, &xpm_mask
,
3459 rc
= XpmReadFileToPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3460 SSDATA (file
), &img
->pixmap
, &img
->mask
,
3462 #endif /* HAVE_NTGUI */
3466 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
3467 if (!STRINGP (buffer
))
3469 image_error ("Invalid image data `%s'", buffer
, Qnil
);
3470 #ifdef ALLOC_XPM_COLORS
3471 xpm_free_color_cache ();
3476 /* XpmCreatePixmapFromBuffer is not available in the Windows port
3477 of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
3478 rc
= fn_XpmCreateImageFromBuffer (&hdc
, SDATA (buffer
),
3479 &xpm_image
, &xpm_mask
,
3482 rc
= XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3484 &img
->pixmap
, &img
->mask
,
3486 #endif /* HAVE_NTGUI */
3489 if (rc
== XpmSuccess
)
3491 #if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS)
3492 img
->colors
= colors_in_color_table (&img
->ncolors
);
3493 #else /* not ALLOC_XPM_COLORS */
3497 /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
3498 plus some duplicate attributes. */
3499 if (xpm_image
&& xpm_image
->bitmap
)
3501 img
->pixmap
= xpm_image
->bitmap
;
3502 /* XImageFree in libXpm frees XImage struct without destroying
3503 the bitmap, which is what we want. */
3504 fn_XImageFree (xpm_image
);
3506 if (xpm_mask
&& xpm_mask
->bitmap
)
3508 /* The mask appears to be inverted compared with what we expect.
3509 TODO: invert our expectations. See other places where we
3510 have to invert bits because our idea of masks is backwards. */
3512 old_obj
= SelectObject (hdc
, xpm_mask
->bitmap
);
3514 PatBlt (hdc
, 0, 0, xpm_mask
->width
, xpm_mask
->height
, DSTINVERT
);
3515 SelectObject (hdc
, old_obj
);
3517 img
->mask
= xpm_mask
->bitmap
;
3518 fn_XImageFree (xpm_mask
);
3523 #endif /* HAVE_NTGUI */
3525 /* Remember allocated colors. */
3526 img
->ncolors
= attrs
.nalloc_pixels
;
3527 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
3528 * sizeof *img
->colors
);
3529 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
3531 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
3532 #ifdef DEBUG_X_COLORS
3533 register_color (img
->colors
[i
]);
3536 #endif /* not ALLOC_XPM_COLORS */
3538 img
->width
= attrs
.width
;
3539 img
->height
= attrs
.height
;
3540 xassert (img
->width
> 0 && img
->height
> 0);
3542 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
3544 fn_XpmFreeAttributes (&attrs
);
3546 XpmFreeAttributes (&attrs
);
3547 #endif /* HAVE_NTGUI */
3553 #endif /* HAVE_NTGUI */
3558 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
3561 case XpmFileInvalid
:
3562 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
3566 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
3569 case XpmColorFailed
:
3570 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
3574 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
3579 #ifdef ALLOC_XPM_COLORS
3580 xpm_free_color_cache ();
3582 return rc
== XpmSuccess
;
3585 #endif /* HAVE_XPM */
3587 #if defined (HAVE_NS) && !defined (HAVE_XPM)
3589 /* XPM support functions for NS where libxpm is not available.
3590 Only XPM version 3 (without any extensions) is supported. */
3592 static int xpm_scan (const unsigned char **, const unsigned char *,
3593 const unsigned char **, int *);
3594 static Lisp_Object xpm_make_color_table_v
3595 (void (**) (Lisp_Object
, const unsigned char *, int, Lisp_Object
),
3596 Lisp_Object (**) (Lisp_Object
, const unsigned char *, int));
3597 static void xpm_put_color_table_v (Lisp_Object
, const unsigned char *,
3599 static Lisp_Object
xpm_get_color_table_v (Lisp_Object
,
3600 const unsigned char *, int);
3601 static Lisp_Object xpm_make_color_table_h
3602 (void (**) (Lisp_Object
, const unsigned char *, int, Lisp_Object
),
3603 Lisp_Object (**) (Lisp_Object
, const unsigned char *, int));
3604 static void xpm_put_color_table_h (Lisp_Object
, const unsigned char *,
3606 static Lisp_Object
xpm_get_color_table_h (Lisp_Object
,
3607 const unsigned char *, int);
3608 static int xpm_str_to_color_key (const char *);
3609 static int xpm_load_image (struct frame
*, struct image
*,
3610 const unsigned char *, const unsigned char *);
3612 /* Tokens returned from xpm_scan. */
3621 /* Scan an XPM data and return a character (< 256) or a token defined
3622 by enum xpm_token above. *S and END are the start (inclusive) and
3623 the end (exclusive) addresses of the data, respectively. Advance
3624 *S while scanning. If token is either XPM_TK_IDENT or
3625 XPM_TK_STRING, *BEG and *LEN are set to the start address and the
3626 length of the corresponding token, respectively. */
3629 xpm_scan (const unsigned char **s
,
3630 const unsigned char *end
,
3631 const unsigned char **beg
,
3638 /* Skip white-space. */
3639 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
3642 /* gnus-pointer.xpm uses '-' in its identifier.
3643 sb-dir-plus.xpm uses '+' in its identifier. */
3644 if (isalpha (c
) || c
== '_' || c
== '-' || c
== '+')
3648 && (c
= **s
, isalnum (c
) || c
== '_' || c
== '-' || c
== '+'))
3651 return XPM_TK_IDENT
;
3656 while (*s
< end
&& **s
!= '"')
3661 return XPM_TK_STRING
;
3665 if (*s
< end
&& **s
== '*')
3667 /* C-style comment. */
3671 while (*s
< end
&& *(*s
)++ != '*')
3674 while (*s
< end
&& **s
!= '/');
3688 /* Functions for color table lookup in XPM data. A key is a string
3689 specifying the color of each pixel in XPM data. A value is either
3690 an integer that specifies a pixel color, Qt that specifies
3691 transparency, or Qnil for the unspecified color. If the length of
3692 the key string is one, a vector is used as a table. Otherwise, a
3693 hash table is used. */
3696 xpm_make_color_table_v (void (**put_func
) (Lisp_Object
,
3697 const unsigned char *,
3700 Lisp_Object (**get_func
) (Lisp_Object
,
3701 const unsigned char *,
3704 *put_func
= xpm_put_color_table_v
;
3705 *get_func
= xpm_get_color_table_v
;
3706 return Fmake_vector (make_number (256), Qnil
);
3710 xpm_put_color_table_v (Lisp_Object color_table
,
3711 const unsigned char *chars_start
,
3715 XVECTOR (color_table
)->contents
[*chars_start
] = color
;
3719 xpm_get_color_table_v (Lisp_Object color_table
,
3720 const unsigned char *chars_start
,
3723 return XVECTOR (color_table
)->contents
[*chars_start
];
3727 xpm_make_color_table_h (void (**put_func
) (Lisp_Object
,
3728 const unsigned char *,
3731 Lisp_Object (**get_func
) (Lisp_Object
,
3732 const unsigned char *,
3735 *put_func
= xpm_put_color_table_h
;
3736 *get_func
= xpm_get_color_table_h
;
3737 return make_hash_table (Qequal
, make_number (DEFAULT_HASH_SIZE
),
3738 make_float (DEFAULT_REHASH_SIZE
),
3739 make_float (DEFAULT_REHASH_THRESHOLD
),
3744 xpm_put_color_table_h (Lisp_Object color_table
,
3745 const unsigned char *chars_start
,
3749 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
3750 EMACS_UINT hash_code
;
3751 Lisp_Object chars
= make_unibyte_string (chars_start
, chars_len
);
3753 hash_lookup (table
, chars
, &hash_code
);
3754 hash_put (table
, chars
, color
, hash_code
);
3758 xpm_get_color_table_h (Lisp_Object color_table
,
3759 const unsigned char *chars_start
,
3762 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
3763 int i
= hash_lookup (table
, make_unibyte_string (chars_start
, chars_len
),
3766 return i
>= 0 ? HASH_VALUE (table
, i
) : Qnil
;
3769 enum xpm_color_key
{
3777 static const char xpm_color_key_strings
[][4] = {"s", "m", "g4", "g", "c"};
3780 xpm_str_to_color_key (const char *s
)
3785 i
< sizeof xpm_color_key_strings
/ sizeof xpm_color_key_strings
[0];
3787 if (strcmp (xpm_color_key_strings
[i
], s
) == 0)
3793 xpm_load_image (struct frame
*f
,
3795 const unsigned char *contents
,
3796 const unsigned char *end
)
3798 const unsigned char *s
= contents
, *beg
, *str
;
3799 unsigned char buffer
[BUFSIZ
];
3800 int width
, height
, x
, y
;
3801 int num_colors
, chars_per_pixel
;
3803 void (*put_color_table
) (Lisp_Object
, const unsigned char *, int, Lisp_Object
);
3804 Lisp_Object (*get_color_table
) (Lisp_Object
, const unsigned char *, int);
3805 Lisp_Object frame
, color_symbols
, color_table
;
3806 int best_key
, have_mask
= 0;
3807 XImagePtr ximg
= NULL
, mask_img
= NULL
;
3810 LA1 = xpm_scan (&s, end, &beg, &len)
3812 #define expect(TOKEN) \
3813 if (LA1 != (TOKEN)) \
3818 #define expect_ident(IDENT) \
3819 if (LA1 == XPM_TK_IDENT \
3820 && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
3825 if (!(end
- s
>= 9 && memcmp (s
, "/* XPM */", 9) == 0))
3829 expect_ident ("static");
3830 expect_ident ("char");
3832 expect (XPM_TK_IDENT
);
3837 expect (XPM_TK_STRING
);
3840 memcpy (buffer
, beg
, len
);
3842 if (sscanf (buffer
, "%d %d %d %d", &width
, &height
,
3843 &num_colors
, &chars_per_pixel
) != 4
3844 || width
<= 0 || height
<= 0
3845 || num_colors
<= 0 || chars_per_pixel
<= 0)
3848 if (!check_image_size (f
, width
, height
))
3850 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
3856 XSETFRAME (frame
, f
);
3857 if (!NILP (Fxw_display_color_p (frame
)))
3858 best_key
= XPM_COLOR_KEY_C
;
3859 else if (!NILP (Fx_display_grayscale_p (frame
)))
3860 best_key
= (XFASTINT (Fx_display_planes (frame
)) > 2
3861 ? XPM_COLOR_KEY_G
: XPM_COLOR_KEY_G4
);
3863 best_key
= XPM_COLOR_KEY_M
;
3865 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
3866 if (chars_per_pixel
== 1)
3867 color_table
= xpm_make_color_table_v (&put_color_table
,
3870 color_table
= xpm_make_color_table_h (&put_color_table
,
3873 while (num_colors
-- > 0)
3875 char *color
, *max_color
;
3876 int key
, next_key
, max_key
= 0;
3877 Lisp_Object symbol_color
= Qnil
, color_val
;
3880 expect (XPM_TK_STRING
);
3881 if (len
<= chars_per_pixel
|| len
>= BUFSIZ
+ chars_per_pixel
)
3883 memcpy (buffer
, beg
+ chars_per_pixel
, len
- chars_per_pixel
);
3884 buffer
[len
- chars_per_pixel
] = '\0';
3886 str
= strtok (buffer
, " \t");
3889 key
= xpm_str_to_color_key (str
);
3894 color
= strtok (NULL
, " \t");
3898 while ((str
= strtok (NULL
, " \t")) != NULL
)
3900 next_key
= xpm_str_to_color_key (str
);
3903 color
[strlen (color
)] = ' ';
3906 if (key
== XPM_COLOR_KEY_S
)
3908 if (NILP (symbol_color
))
3909 symbol_color
= build_string (color
);
3911 else if (max_key
< key
&& key
<= best_key
)
3921 if (!NILP (color_symbols
) && !NILP (symbol_color
))
3923 Lisp_Object specified_color
= Fassoc (symbol_color
, color_symbols
);
3925 if (CONSP (specified_color
) && STRINGP (XCDR (specified_color
)))
3927 if (xstrcasecmp (SSDATA (XCDR (specified_color
)), "None") == 0)
3929 else if (x_defined_color (f
, SDATA (XCDR (specified_color
)),
3931 color_val
= make_number (cdef
.pixel
);
3934 if (NILP (color_val
) && max_key
> 0)
3936 if (xstrcasecmp (max_color
, "None") == 0)
3938 else if (x_defined_color (f
, max_color
, &cdef
, 0))
3939 color_val
= make_number (cdef
.pixel
);
3941 if (!NILP (color_val
))
3942 (*put_color_table
) (color_table
, beg
, chars_per_pixel
, color_val
);
3947 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
3948 &ximg
, &img
->pixmap
)
3950 || !x_create_x_image_and_pixmap (f
, width
, height
, 1,
3951 &mask_img
, &img
->mask
)
3955 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
3959 for (y
= 0; y
< height
; y
++)
3961 expect (XPM_TK_STRING
);
3963 if (len
< width
* chars_per_pixel
)
3965 for (x
= 0; x
< width
; x
++, str
+= chars_per_pixel
)
3967 Lisp_Object color_val
=
3968 (*get_color_table
) (color_table
, str
, chars_per_pixel
);
3970 XPutPixel (ximg
, x
, y
,
3971 (INTEGERP (color_val
) ? XINT (color_val
)
3972 : FRAME_FOREGROUND_PIXEL (f
)));
3974 XPutPixel (mask_img
, x
, y
,
3975 (!EQ (color_val
, Qt
) ? PIX_MASK_DRAW
3976 : (have_mask
= 1, PIX_MASK_RETAIN
)));
3978 if (EQ (color_val
, Qt
))
3979 ns_set_alpha (ximg
, x
, y
, 0);
3987 img
->height
= height
;
3989 /* Maybe fill in the background field while we have ximg handy. */
3990 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
3991 IMAGE_BACKGROUND (img
, f
, ximg
);
3993 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
3994 x_destroy_x_image (ximg
);
3998 /* Fill in the background_transparent field while we have the
4000 image_background_transparent (img
, f
, mask_img
);
4002 x_put_x_image (f
, mask_img
, img
->mask
, width
, height
);
4003 x_destroy_x_image (mask_img
);
4007 x_destroy_x_image (mask_img
);
4008 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4009 img
->mask
= NO_PIXMAP
;
4015 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
4017 x_destroy_x_image (ximg
);
4018 x_destroy_x_image (mask_img
);
4019 x_clear_image (f
, img
);
4028 xpm_load (struct frame
*f
,
4032 Lisp_Object file_name
;
4034 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4035 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
4036 if (STRINGP (file_name
))
4039 unsigned char *contents
;
4042 file
= x_find_image_file (file_name
);
4043 if (!STRINGP (file
))
4045 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
4049 contents
= slurp_file (SDATA (file
), &size
);
4050 if (contents
== NULL
)
4052 image_error ("Error loading XPM image `%s'", img
->spec
, Qnil
);
4056 success_p
= xpm_load_image (f
, img
, contents
, contents
+ size
);
4063 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
4064 if (!STRINGP (data
))
4066 image_error ("Invalid image data `%s'", data
, Qnil
);
4069 success_p
= xpm_load_image (f
, img
, SDATA (data
),
4070 SDATA (data
) + SBYTES (data
));
4076 #endif /* HAVE_NS && !HAVE_XPM */
4080 /***********************************************************************
4082 ***********************************************************************/
4084 #ifdef COLOR_TABLE_SUPPORT
4086 /* An entry in the color table mapping an RGB color to a pixel color. */
4091 unsigned long pixel
;
4093 /* Next in color table collision list. */
4094 struct ct_color
*next
;
4097 /* The bucket vector size to use. Must be prime. */
4101 /* Value is a hash of the RGB color given by R, G, and B. */
4103 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
4105 /* The color hash table. */
4107 static struct ct_color
**ct_table
;
4109 /* Number of entries in the color table. */
4111 static int ct_colors_allocated
;
4113 /* Initialize the color table. */
4116 init_color_table (void)
4118 int size
= CT_SIZE
* sizeof (*ct_table
);
4119 ct_table
= (struct ct_color
**) xmalloc (size
);
4120 memset (ct_table
, 0, size
);
4121 ct_colors_allocated
= 0;
4125 /* Free memory associated with the color table. */
4128 free_color_table (void)
4131 struct ct_color
*p
, *next
;
4133 for (i
= 0; i
< CT_SIZE
; ++i
)
4134 for (p
= ct_table
[i
]; p
; p
= next
)
4145 /* Value is a pixel color for RGB color R, G, B on frame F. If an
4146 entry for that color already is in the color table, return the
4147 pixel color of that entry. Otherwise, allocate a new color for R,
4148 G, B, and make an entry in the color table. */
4150 static unsigned long
4151 lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
)
4153 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
4154 int i
= hash
% CT_SIZE
;
4156 Display_Info
*dpyinfo
;
4158 /* Handle TrueColor visuals specially, which improves performance by
4159 two orders of magnitude. Freeing colors on TrueColor visuals is
4160 a nop, and pixel colors specify RGB values directly. See also
4161 the Xlib spec, chapter 3.1. */
4162 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
4163 if (dpyinfo
->red_bits
> 0)
4165 unsigned long pr
, pg
, pb
;
4167 /* Apply gamma-correction like normal color allocation does. */
4171 color
.red
= r
, color
.green
= g
, color
.blue
= b
;
4172 gamma_correct (f
, &color
);
4173 r
= color
.red
, g
= color
.green
, b
= color
.blue
;
4176 /* Scale down RGB values to the visual's bits per RGB, and shift
4177 them to the right position in the pixel color. Note that the
4178 original RGB values are 16-bit values, as usual in X. */
4179 pr
= (r
>> (16 - dpyinfo
->red_bits
)) << dpyinfo
->red_offset
;
4180 pg
= (g
>> (16 - dpyinfo
->green_bits
)) << dpyinfo
->green_offset
;
4181 pb
= (b
>> (16 - dpyinfo
->blue_bits
)) << dpyinfo
->blue_offset
;
4183 /* Assemble the pixel color. */
4184 return pr
| pg
| pb
;
4187 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4188 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
4194 #ifdef HAVE_X_WINDOWS
4203 cmap
= FRAME_X_COLORMAP (f
);
4204 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4207 ++ct_colors_allocated
;
4208 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4212 p
->pixel
= color
.pixel
;
4213 p
->next
= ct_table
[i
];
4217 return FRAME_FOREGROUND_PIXEL (f
);
4222 color
= PALETTERGB (r
, g
, b
);
4224 color
= RGB_TO_ULONG (r
, g
, b
);
4225 #endif /* HAVE_NTGUI */
4226 ++ct_colors_allocated
;
4227 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4232 p
->next
= ct_table
[i
];
4234 #endif /* HAVE_X_WINDOWS */
4242 /* Look up pixel color PIXEL which is used on frame F in the color
4243 table. If not already present, allocate it. Value is PIXEL. */
4245 static unsigned long
4246 lookup_pixel_color (struct frame
*f
, unsigned long pixel
)
4248 int i
= pixel
% CT_SIZE
;
4251 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4252 if (p
->pixel
== pixel
)
4261 #ifdef HAVE_X_WINDOWS
4262 cmap
= FRAME_X_COLORMAP (f
);
4263 color
.pixel
= pixel
;
4264 x_query_color (f
, &color
);
4265 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4268 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
4269 color
.pixel
= pixel
;
4270 XQueryColor (NULL
, cmap
, &color
);
4271 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4273 #endif /* HAVE_X_WINDOWS */
4277 ++ct_colors_allocated
;
4279 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4284 p
->next
= ct_table
[i
];
4288 return FRAME_FOREGROUND_PIXEL (f
);
4294 /* Value is a vector of all pixel colors contained in the color table,
4295 allocated via xmalloc. Set *N to the number of colors. */
4297 static unsigned long *
4298 colors_in_color_table (int *n
)
4302 unsigned long *colors
;
4304 if (ct_colors_allocated
== 0)
4311 colors
= (unsigned long *) xmalloc (ct_colors_allocated
4313 *n
= ct_colors_allocated
;
4315 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
4316 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4317 colors
[j
++] = p
->pixel
;
4323 #else /* COLOR_TABLE_SUPPORT */
4325 static unsigned long
4326 lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
)
4328 unsigned long pixel
;
4331 pixel
= PALETTERGB (r
>> 8, g
>> 8, b
>> 8);
4332 #endif /* HAVE_NTGUI */
4335 pixel
= RGB_TO_ULONG (r
>> 8, g
>> 8, b
>> 8);
4336 #endif /* HAVE_NS */
4341 init_color_table (void)
4344 #endif /* COLOR_TABLE_SUPPORT */
4347 /***********************************************************************
4349 ***********************************************************************/
4351 static XColor
*x_to_xcolors (struct frame
*, struct image
*, int);
4352 static void x_from_xcolors (struct frame
*, struct image
*, XColor
*);
4353 static void x_detect_edges (struct frame
*, struct image
*, int[9], int);
4356 static void XPutPixel (XImagePtr
, int, int, COLORREF
);
4357 #endif /* HAVE_NTGUI */
4359 /* Edge detection matrices for different edge-detection
4362 static int emboss_matrix
[9] = {
4364 2, -1, 0, /* y - 1 */
4366 0, 1, -2 /* y + 1 */
4369 static int laplace_matrix
[9] = {
4371 1, 0, 0, /* y - 1 */
4373 0, 0, -1 /* y + 1 */
4376 /* Value is the intensity of the color whose red/green/blue values
4379 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
4382 /* On frame F, return an array of XColor structures describing image
4383 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
4384 non-zero means also fill the red/green/blue members of the XColor
4385 structures. Value is a pointer to the array of XColors structures,
4386 allocated with xmalloc; it must be freed by the caller. */
4389 x_to_xcolors (struct frame
*f
, struct image
*img
, int rgb_p
)
4393 XImagePtr_or_DC ximg
;
4397 #endif /* HAVE_NTGUI */
4399 colors
= (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *colors
);
4402 /* Get the X image IMG->pixmap. */
4403 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
4404 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4406 /* Load the image into a memory device context. */
4407 hdc
= get_frame_dc (f
);
4408 ximg
= CreateCompatibleDC (hdc
);
4409 release_frame_dc (f
, hdc
);
4410 prev
= SelectObject (ximg
, img
->pixmap
);
4411 #endif /* HAVE_NTGUI */
4413 /* Fill the `pixel' members of the XColor array. I wished there
4414 were an easy and portable way to circumvent XGetPixel. */
4416 for (y
= 0; y
< img
->height
; ++y
)
4420 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
4421 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4422 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4424 x_query_colors (f
, row
, img
->width
);
4428 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4430 /* W32_TODO: palette support needed here? */
4431 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4434 p
->red
= RED16_FROM_ULONG (p
->pixel
);
4435 p
->green
= GREEN16_FROM_ULONG (p
->pixel
);
4436 p
->blue
= BLUE16_FROM_ULONG (p
->pixel
);
4439 #endif /* HAVE_X_WINDOWS */
4442 Destroy_Image (ximg
, prev
);
4449 /* Put a pixel of COLOR at position X, Y in XIMG. XIMG must have been
4450 created with CreateDIBSection, with the pointer to the bit values
4451 stored in ximg->data. */
4454 XPutPixel (XImagePtr ximg
, int x
, int y
, COLORREF color
)
4456 int width
= ximg
->info
.bmiHeader
.biWidth
;
4457 unsigned char * pixel
;
4459 /* True color images. */
4460 if (ximg
->info
.bmiHeader
.biBitCount
== 24)
4462 int rowbytes
= width
* 3;
4463 /* Ensure scanlines are aligned on 4 byte boundaries. */
4465 rowbytes
+= 4 - (rowbytes
% 4);
4467 pixel
= ximg
->data
+ y
* rowbytes
+ x
* 3;
4468 /* Windows bitmaps are in BGR order. */
4469 *pixel
= GetBValue (color
);
4470 *(pixel
+ 1) = GetGValue (color
);
4471 *(pixel
+ 2) = GetRValue (color
);
4473 /* Monochrome images. */
4474 else if (ximg
->info
.bmiHeader
.biBitCount
== 1)
4476 int rowbytes
= width
/ 8;
4477 /* Ensure scanlines are aligned on 4 byte boundaries. */
4479 rowbytes
+= 4 - (rowbytes
% 4);
4480 pixel
= ximg
->data
+ y
* rowbytes
+ x
/ 8;
4481 /* Filter out palette info. */
4482 if (color
& 0x00ffffff)
4483 *pixel
= *pixel
| (1 << x
% 8);
4485 *pixel
= *pixel
& ~(1 << x
% 8);
4488 image_error ("XPutPixel: palette image not supported", Qnil
, Qnil
);
4491 #endif /* HAVE_NTGUI */
4493 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
4494 RGB members are set. F is the frame on which this all happens.
4495 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
4498 x_from_xcolors (struct frame
*f
, struct image
*img
, XColor
*colors
)
4501 XImagePtr oimg
= NULL
;
4505 init_color_table ();
4507 x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
4510 for (y
= 0; y
< img
->height
; ++y
)
4511 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4513 unsigned long pixel
;
4514 pixel
= lookup_rgb_color (f
, p
->red
, p
->green
, p
->blue
);
4515 XPutPixel (oimg
, x
, y
, pixel
);
4519 x_clear_image_1 (f
, img
, 1, 0, 1);
4521 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
4522 x_destroy_x_image (oimg
);
4523 img
->pixmap
= pixmap
;
4524 #ifdef COLOR_TABLE_SUPPORT
4525 img
->colors
= colors_in_color_table (&img
->ncolors
);
4526 free_color_table ();
4527 #endif /* COLOR_TABLE_SUPPORT */
4531 /* On frame F, perform edge-detection on image IMG.
4533 MATRIX is a nine-element array specifying the transformation
4534 matrix. See emboss_matrix for an example.
4536 COLOR_ADJUST is a color adjustment added to each pixel of the
4540 x_detect_edges (struct frame
*f
, struct image
*img
, int *matrix
, int color_adjust
)
4542 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4546 for (i
= sum
= 0; i
< 9; ++i
)
4547 sum
+= eabs (matrix
[i
]);
4549 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
4551 new = (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *new);
4553 for (y
= 0; y
< img
->height
; ++y
)
4555 p
= COLOR (new, 0, y
);
4556 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4557 p
= COLOR (new, img
->width
- 1, y
);
4558 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4561 for (x
= 1; x
< img
->width
- 1; ++x
)
4563 p
= COLOR (new, x
, 0);
4564 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4565 p
= COLOR (new, x
, img
->height
- 1);
4566 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4569 for (y
= 1; y
< img
->height
- 1; ++y
)
4571 p
= COLOR (new, 1, y
);
4573 for (x
= 1; x
< img
->width
- 1; ++x
, ++p
)
4575 int r
, g
, b
, yy
, xx
;
4578 for (yy
= y
- 1; yy
< y
+ 2; ++yy
)
4579 for (xx
= x
- 1; xx
< x
+ 2; ++xx
, ++i
)
4582 XColor
*t
= COLOR (colors
, xx
, yy
);
4583 r
+= matrix
[i
] * t
->red
;
4584 g
+= matrix
[i
] * t
->green
;
4585 b
+= matrix
[i
] * t
->blue
;
4588 r
= (r
/ sum
+ color_adjust
) & 0xffff;
4589 g
= (g
/ sum
+ color_adjust
) & 0xffff;
4590 b
= (b
/ sum
+ color_adjust
) & 0xffff;
4591 p
->red
= p
->green
= p
->blue
= COLOR_INTENSITY (r
, g
, b
);
4596 x_from_xcolors (f
, img
, new);
4602 /* Perform the pre-defined `emboss' edge-detection on image IMG
4606 x_emboss (struct frame
*f
, struct image
*img
)
4608 x_detect_edges (f
, img
, emboss_matrix
, 0xffff / 2);
4612 /* Transform image IMG which is used on frame F with a Laplace
4613 edge-detection algorithm. The result is an image that can be used
4614 to draw disabled buttons, for example. */
4617 x_laplace (struct frame
*f
, struct image
*img
)
4619 x_detect_edges (f
, img
, laplace_matrix
, 45000);
4623 /* Perform edge-detection on image IMG on frame F, with specified
4624 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
4626 MATRIX must be either
4628 - a list of at least 9 numbers in row-major form
4629 - a vector of at least 9 numbers
4631 COLOR_ADJUST nil means use a default; otherwise it must be a
4635 x_edge_detection (struct frame
*f
, struct image
*img
, Lisp_Object matrix
,
4636 Lisp_Object color_adjust
)
4644 i
< 9 && CONSP (matrix
) && NUMBERP (XCAR (matrix
));
4645 ++i
, matrix
= XCDR (matrix
))
4646 trans
[i
] = XFLOATINT (XCAR (matrix
));
4648 else if (VECTORP (matrix
) && ASIZE (matrix
) >= 9)
4650 for (i
= 0; i
< 9 && NUMBERP (AREF (matrix
, i
)); ++i
)
4651 trans
[i
] = XFLOATINT (AREF (matrix
, i
));
4654 if (NILP (color_adjust
))
4655 color_adjust
= make_number (0xffff / 2);
4657 if (i
== 9 && NUMBERP (color_adjust
))
4658 x_detect_edges (f
, img
, trans
, XFLOATINT (color_adjust
));
4662 /* Transform image IMG on frame F so that it looks disabled. */
4665 x_disable_image (struct frame
*f
, struct image
*img
)
4667 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
4669 int n_planes
= dpyinfo
->n_planes
* dpyinfo
->n_cbits
;
4671 int n_planes
= dpyinfo
->n_planes
;
4672 #endif /* HAVE_NTGUI */
4676 /* Color (or grayscale). Convert to gray, and equalize. Just
4677 drawing such images with a stipple can look very odd, so
4678 we're using this method instead. */
4679 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4681 const int h
= 15000;
4682 const int l
= 30000;
4684 for (p
= colors
, end
= colors
+ img
->width
* img
->height
;
4688 int i
= COLOR_INTENSITY (p
->red
, p
->green
, p
->blue
);
4689 int i2
= (0xffff - h
- l
) * i
/ 0xffff + l
;
4690 p
->red
= p
->green
= p
->blue
= i2
;
4693 x_from_xcolors (f
, img
, colors
);
4696 /* Draw a cross over the disabled image, if we must or if we
4698 if (n_planes
< 2 || cross_disabled_images
)
4701 Display
*dpy
= FRAME_X_DISPLAY (f
);
4704 #ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
4706 #define MaskForeground(f) WHITE_PIX_DEFAULT (f)
4708 gc
= XCreateGC (dpy
, img
->pixmap
, 0, NULL
);
4709 XSetForeground (dpy
, gc
, BLACK_PIX_DEFAULT (f
));
4710 XDrawLine (dpy
, img
->pixmap
, gc
, 0, 0,
4711 img
->width
- 1, img
->height
- 1);
4712 XDrawLine (dpy
, img
->pixmap
, gc
, 0, img
->height
- 1,
4718 gc
= XCreateGC (dpy
, img
->mask
, 0, NULL
);
4719 XSetForeground (dpy
, gc
, MaskForeground (f
));
4720 XDrawLine (dpy
, img
->mask
, gc
, 0, 0,
4721 img
->width
- 1, img
->height
- 1);
4722 XDrawLine (dpy
, img
->mask
, gc
, 0, img
->height
- 1,
4726 #endif /* !HAVE_NS */
4731 hdc
= get_frame_dc (f
);
4732 bmpdc
= CreateCompatibleDC (hdc
);
4733 release_frame_dc (f
, hdc
);
4735 prev
= SelectObject (bmpdc
, img
->pixmap
);
4737 SetTextColor (bmpdc
, BLACK_PIX_DEFAULT (f
));
4738 MoveToEx (bmpdc
, 0, 0, NULL
);
4739 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
4740 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
4741 LineTo (bmpdc
, img
->width
- 1, 0);
4745 SelectObject (bmpdc
, img
->mask
);
4746 SetTextColor (bmpdc
, WHITE_PIX_DEFAULT (f
));
4747 MoveToEx (bmpdc
, 0, 0, NULL
);
4748 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
4749 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
4750 LineTo (bmpdc
, img
->width
- 1, 0);
4752 SelectObject (bmpdc
, prev
);
4754 #endif /* HAVE_NTGUI */
4759 /* Build a mask for image IMG which is used on frame F. FILE is the
4760 name of an image file, for error messages. HOW determines how to
4761 determine the background color of IMG. If it is a list '(R G B)',
4762 with R, G, and B being integers >= 0, take that as the color of the
4763 background. Otherwise, determine the background color of IMG
4764 heuristically. Value is non-zero if successful. */
4767 x_build_heuristic_mask (struct frame
*f
, struct image
*img
, Lisp_Object how
)
4769 XImagePtr_or_DC ximg
;
4777 #endif /* HAVE_NTGUI */
4778 int x
, y
, rc
, use_img_background
;
4779 unsigned long bg
= 0;
4783 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4784 img
->mask
= NO_PIXMAP
;
4785 img
->background_transparent_valid
= 0;
4790 /* Create an image and pixmap serving as mask. */
4791 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
4792 &mask_img
, &img
->mask
);
4795 #endif /* !HAVE_NS */
4797 /* Get the X image of IMG->pixmap. */
4798 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
, 0, 0,
4799 img
->width
, img
->height
,
4802 /* Create the bit array serving as mask. */
4803 row_width
= (img
->width
+ 7) / 8;
4804 mask_img
= xmalloc (row_width
* img
->height
);
4805 memset (mask_img
, 0, row_width
* img
->height
);
4807 /* Create a memory device context for IMG->pixmap. */
4808 frame_dc
= get_frame_dc (f
);
4809 ximg
= CreateCompatibleDC (frame_dc
);
4810 release_frame_dc (f
, frame_dc
);
4811 prev
= SelectObject (ximg
, img
->pixmap
);
4812 #endif /* HAVE_NTGUI */
4814 /* Determine the background color of ximg. If HOW is `(R G B)'
4815 take that as color. Otherwise, use the image's background color. */
4816 use_img_background
= 1;
4822 for (i
= 0; i
< 3 && CONSP (how
) && NATNUMP (XCAR (how
)); ++i
)
4824 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
4828 if (i
== 3 && NILP (how
))
4830 char color_name
[30];
4831 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
4834 0x00ffffff & /* Filter out palette info. */
4835 #endif /* HAVE_NTGUI */
4836 x_alloc_image_color (f
, img
, build_string (color_name
), 0));
4837 use_img_background
= 0;
4841 if (use_img_background
)
4842 bg
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
4844 /* Set all bits in mask_img to 1 whose color in ximg is different
4845 from the background color bg. */
4847 for (y
= 0; y
< img
->height
; ++y
)
4848 for (x
= 0; x
< img
->width
; ++x
)
4850 XPutPixel (mask_img
, x
, y
, (XGetPixel (ximg
, x
, y
) != bg
4851 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
));
4853 if (XGetPixel (ximg
, x
, y
) == bg
)
4854 ns_set_alpha (ximg
, x
, y
, 0);
4855 #endif /* HAVE_NS */
4857 /* Fill in the background_transparent field while we have the mask handy. */
4858 image_background_transparent (img
, f
, mask_img
);
4860 /* Put mask_img into img->mask. */
4861 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
4862 x_destroy_x_image (mask_img
);
4863 #endif /* !HAVE_NS */
4865 for (y
= 0; y
< img
->height
; ++y
)
4866 for (x
= 0; x
< img
->width
; ++x
)
4868 COLORREF p
= GetPixel (ximg
, x
, y
);
4870 mask_img
[y
* row_width
+ x
/ 8] |= 1 << (x
% 8);
4873 /* Create the mask image. */
4874 img
->mask
= w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
,
4876 /* Fill in the background_transparent field while we have the mask handy. */
4877 SelectObject (ximg
, img
->mask
);
4878 image_background_transparent (img
, f
, ximg
);
4880 /* Was: x_destroy_x_image ((XImagePtr )mask_img); which seems bogus ++kfs */
4882 #endif /* HAVE_NTGUI */
4884 Destroy_Image (ximg
, prev
);
4890 /***********************************************************************
4891 PBM (mono, gray, color)
4892 ***********************************************************************/
4894 static int pbm_image_p (Lisp_Object object
);
4895 static int pbm_load (struct frame
*f
, struct image
*img
);
4896 static int pbm_scan_number (unsigned char **, unsigned char *);
4898 /* The symbol `pbm' identifying images of this type. */
4900 static Lisp_Object Qpbm
;
4902 /* Indices of image specification fields in gs_format, below. */
4904 enum pbm_keyword_index
4920 /* Vector of image_keyword structures describing the format
4921 of valid user-defined image specifications. */
4923 static const struct image_keyword pbm_format
[PBM_LAST
] =
4925 {":type", IMAGE_SYMBOL_VALUE
, 1},
4926 {":file", IMAGE_STRING_VALUE
, 0},
4927 {":data", IMAGE_STRING_VALUE
, 0},
4928 {":ascent", IMAGE_ASCENT_VALUE
, 0},
4929 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
4930 {":relief", IMAGE_INTEGER_VALUE
, 0},
4931 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4932 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4933 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4934 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
4935 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
4938 /* Structure describing the image type `pbm'. */
4940 static struct image_type pbm_type
=
4950 /* Return non-zero if OBJECT is a valid PBM image specification. */
4953 pbm_image_p (Lisp_Object object
)
4955 struct image_keyword fmt
[PBM_LAST
];
4957 memcpy (fmt
, pbm_format
, sizeof fmt
);
4959 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
))
4962 /* Must specify either :data or :file. */
4963 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
4967 /* Scan a decimal number from *S and return it. Advance *S while
4968 reading the number. END is the end of the string. Value is -1 at
4972 pbm_scan_number (unsigned char **s
, unsigned char *end
)
4974 int c
= 0, val
= -1;
4978 /* Skip white-space. */
4979 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
4984 /* Skip comment to end of line. */
4985 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
4988 else if (isdigit (c
))
4990 /* Read decimal number. */
4992 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
4993 val
= 10 * val
+ c
- '0';
5005 #if 0 /* Unused. ++kfs */
5007 /* Read FILE into memory. Value is a pointer to a buffer allocated
5008 with xmalloc holding FILE's contents. Value is null if an error
5009 occurred. *SIZE is set to the size of the file. */
5012 pbm_read_file (file
, size
)
5020 if (stat (SDATA (file
), &st
) == 0
5021 && (fp
= fopen (SDATA (file
), "rb")) != NULL
5022 && 0 <= st
.st_size
&& st
.st_size
<= min (PTRDIFF_MAX
, SIZE_MAX
)
5023 && (buf
= (char *) xmalloc (st
.st_size
),
5024 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
5043 #endif /* HAVE_NTGUI */
5045 /* Load PBM image IMG for use on frame F. */
5048 pbm_load (struct frame
*f
, struct image
*img
)
5051 int width
, height
, max_color_idx
= 0;
5053 Lisp_Object file
, specified_file
;
5054 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
5055 unsigned char *contents
= NULL
;
5056 unsigned char *end
, *p
;
5059 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5061 if (STRINGP (specified_file
))
5063 file
= x_find_image_file (specified_file
);
5064 if (!STRINGP (file
))
5066 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5070 contents
= slurp_file (SSDATA (file
), &size
);
5071 if (contents
== NULL
)
5073 image_error ("Error reading `%s'", file
, Qnil
);
5078 end
= contents
+ size
;
5083 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5084 if (!STRINGP (data
))
5086 image_error ("Invalid image data `%s'", data
, Qnil
);
5090 end
= p
+ SBYTES (data
);
5093 /* Check magic number. */
5094 if (end
- p
< 2 || *p
++ != 'P')
5096 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5105 raw_p
= 0, type
= PBM_MONO
;
5109 raw_p
= 0, type
= PBM_GRAY
;
5113 raw_p
= 0, type
= PBM_COLOR
;
5117 raw_p
= 1, type
= PBM_MONO
;
5121 raw_p
= 1, type
= PBM_GRAY
;
5125 raw_p
= 1, type
= PBM_COLOR
;
5129 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5133 /* Read width, height, maximum color-component. Characters
5134 starting with `#' up to the end of a line are ignored. */
5135 width
= pbm_scan_number (&p
, end
);
5136 height
= pbm_scan_number (&p
, end
);
5138 if (type
!= PBM_MONO
)
5140 max_color_idx
= pbm_scan_number (&p
, end
);
5141 if (max_color_idx
> 65535 || max_color_idx
< 0)
5143 image_error ("Unsupported maximum PBM color value", Qnil
, Qnil
);
5148 if (!check_image_size (f
, width
, height
))
5150 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
5154 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
5155 &ximg
, &img
->pixmap
))
5158 /* Initialize the color hash table. */
5159 init_color_table ();
5161 if (type
== PBM_MONO
)
5164 struct image_keyword fmt
[PBM_LAST
];
5165 unsigned long fg
= FRAME_FOREGROUND_PIXEL (f
);
5166 unsigned long bg
= FRAME_BACKGROUND_PIXEL (f
);
5168 /* Parse the image specification. */
5169 memcpy (fmt
, pbm_format
, sizeof fmt
);
5170 parse_image_spec (img
->spec
, fmt
, PBM_LAST
, Qpbm
);
5172 /* Get foreground and background colors, maybe allocate colors. */
5173 if (fmt
[PBM_FOREGROUND
].count
5174 && STRINGP (fmt
[PBM_FOREGROUND
].value
))
5175 fg
= x_alloc_image_color (f
, img
, fmt
[PBM_FOREGROUND
].value
, fg
);
5176 if (fmt
[PBM_BACKGROUND
].count
5177 && STRINGP (fmt
[PBM_BACKGROUND
].value
))
5179 bg
= x_alloc_image_color (f
, img
, fmt
[PBM_BACKGROUND
].value
, bg
);
5180 img
->background
= bg
;
5181 img
->background_valid
= 1;
5184 for (y
= 0; y
< height
; ++y
)
5185 for (x
= 0; x
< width
; ++x
)
5193 x_destroy_x_image (ximg
);
5194 x_clear_image (f
, img
);
5195 image_error ("Invalid image size in image `%s'",
5205 g
= pbm_scan_number (&p
, end
);
5207 XPutPixel (ximg
, x
, y
, g
? fg
: bg
);
5212 int expected_size
= height
* width
;
5213 if (max_color_idx
> 255)
5215 if (type
== PBM_COLOR
)
5218 if (raw_p
&& p
+ expected_size
> end
)
5220 x_destroy_x_image (ximg
);
5221 x_clear_image (f
, img
);
5222 image_error ("Invalid image size in image `%s'",
5227 for (y
= 0; y
< height
; ++y
)
5228 for (x
= 0; x
< width
; ++x
)
5232 if (type
== PBM_GRAY
&& raw_p
)
5235 if (max_color_idx
> 255)
5236 r
= g
= b
= r
* 256 + *p
++;
5238 else if (type
== PBM_GRAY
)
5239 r
= g
= b
= pbm_scan_number (&p
, end
);
5243 if (max_color_idx
> 255)
5246 if (max_color_idx
> 255)
5249 if (max_color_idx
> 255)
5254 r
= pbm_scan_number (&p
, end
);
5255 g
= pbm_scan_number (&p
, end
);
5256 b
= pbm_scan_number (&p
, end
);
5259 if (r
< 0 || g
< 0 || b
< 0)
5261 x_destroy_x_image (ximg
);
5262 image_error ("Invalid pixel value in image `%s'",
5267 /* RGB values are now in the range 0..max_color_idx.
5268 Scale this to the range 0..0xffff supported by X. */
5269 r
= (double) r
* 65535 / max_color_idx
;
5270 g
= (double) g
* 65535 / max_color_idx
;
5271 b
= (double) b
* 65535 / max_color_idx
;
5272 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
5276 #ifdef COLOR_TABLE_SUPPORT
5277 /* Store in IMG->colors the colors allocated for the image, and
5278 free the color table. */
5279 img
->colors
= colors_in_color_table (&img
->ncolors
);
5280 free_color_table ();
5281 #endif /* COLOR_TABLE_SUPPORT */
5284 img
->height
= height
;
5286 /* Maybe fill in the background field while we have ximg handy. */
5288 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
5289 /* Casting avoids a GCC warning. */
5290 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
5292 /* Put the image into a pixmap. */
5293 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
5294 x_destroy_x_image (ximg
);
5296 /* X and W32 versions did it here, MAC version above. ++kfs
5298 img->height = height; */
5305 /***********************************************************************
5307 ***********************************************************************/
5309 #if defined (HAVE_PNG) || defined (HAVE_NS)
5311 /* Function prototypes. */
5313 static int png_image_p (Lisp_Object object
);
5314 static int png_load (struct frame
*f
, struct image
*img
);
5316 /* The symbol `png' identifying images of this type. */
5318 static Lisp_Object Qpng
;
5320 /* Indices of image specification fields in png_format, below. */
5322 enum png_keyword_index
5337 /* Vector of image_keyword structures describing the format
5338 of valid user-defined image specifications. */
5340 static const struct image_keyword png_format
[PNG_LAST
] =
5342 {":type", IMAGE_SYMBOL_VALUE
, 1},
5343 {":data", IMAGE_STRING_VALUE
, 0},
5344 {":file", IMAGE_STRING_VALUE
, 0},
5345 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5346 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5347 {":relief", IMAGE_INTEGER_VALUE
, 0},
5348 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5349 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5350 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5351 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
5354 /* Structure describing the image type `png'. */
5356 static struct image_type png_type
=
5365 /* Return non-zero if OBJECT is a valid PNG image specification. */
5368 png_image_p (Lisp_Object object
)
5370 struct image_keyword fmt
[PNG_LAST
];
5371 memcpy (fmt
, png_format
, sizeof fmt
);
5373 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
5376 /* Must specify either the :data or :file keyword. */
5377 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
5380 #endif /* HAVE_PNG || HAVE_NS */
5386 /* PNG library details. */
5388 DEF_IMGLIB_FN (png_voidp
, png_get_io_ptr
, (png_structp
));
5389 DEF_IMGLIB_FN (int, png_sig_cmp
, (png_bytep
, png_size_t
, png_size_t
));
5390 DEF_IMGLIB_FN (png_structp
, png_create_read_struct
, (png_const_charp
, png_voidp
,
5391 png_error_ptr
, png_error_ptr
));
5392 DEF_IMGLIB_FN (png_infop
, png_create_info_struct
, (png_structp
));
5393 DEF_IMGLIB_FN (void, png_destroy_read_struct
, (png_structpp
, png_infopp
, png_infopp
));
5394 DEF_IMGLIB_FN (void, png_set_read_fn
, (png_structp
, png_voidp
, png_rw_ptr
));
5395 DEF_IMGLIB_FN (void, png_set_sig_bytes
, (png_structp
, int));
5396 DEF_IMGLIB_FN (void, png_read_info
, (png_structp
, png_infop
));
5397 DEF_IMGLIB_FN (png_uint_32
, png_get_IHDR
, (png_structp
, png_infop
,
5398 png_uint_32
*, png_uint_32
*,
5399 int *, int *, int *, int *, int *));
5400 DEF_IMGLIB_FN (png_uint_32
, png_get_valid
, (png_structp
, png_infop
, png_uint_32
));
5401 DEF_IMGLIB_FN (void, png_set_strip_16
, (png_structp
));
5402 DEF_IMGLIB_FN (void, png_set_expand
, (png_structp
));
5403 DEF_IMGLIB_FN (void, png_set_gray_to_rgb
, (png_structp
));
5404 DEF_IMGLIB_FN (void, png_set_background
, (png_structp
, png_color_16p
,
5406 DEF_IMGLIB_FN (png_uint_32
, png_get_bKGD
, (png_structp
, png_infop
, png_color_16p
*));
5407 DEF_IMGLIB_FN (void, png_read_update_info
, (png_structp
, png_infop
));
5408 DEF_IMGLIB_FN (png_byte
, png_get_channels
, (png_structp
, png_infop
));
5409 DEF_IMGLIB_FN (png_size_t
, png_get_rowbytes
, (png_structp
, png_infop
));
5410 DEF_IMGLIB_FN (void, png_read_image
, (png_structp
, png_bytepp
));
5411 DEF_IMGLIB_FN (void, png_read_end
, (png_structp
, png_infop
));
5412 DEF_IMGLIB_FN (void, png_error
, (png_structp
, png_const_charp
));
5414 #if (PNG_LIBPNG_VER >= 10500)
5415 DEF_IMGLIB_FN (void, png_longjmp
, (png_structp
, int));
5416 DEF_IMGLIB_FN (jmp_buf *, png_set_longjmp_fn
, (png_structp
, png_longjmp_ptr
, size_t));
5417 #endif /* libpng version >= 1.5 */
5420 init_png_functions (Lisp_Object libraries
)
5424 if (!(library
= w32_delayed_load (libraries
, Qpng
)))
5427 LOAD_IMGLIB_FN (library
, png_get_io_ptr
);
5428 LOAD_IMGLIB_FN (library
, png_sig_cmp
);
5429 LOAD_IMGLIB_FN (library
, png_create_read_struct
);
5430 LOAD_IMGLIB_FN (library
, png_create_info_struct
);
5431 LOAD_IMGLIB_FN (library
, png_destroy_read_struct
);
5432 LOAD_IMGLIB_FN (library
, png_set_read_fn
);
5433 LOAD_IMGLIB_FN (library
, png_set_sig_bytes
);
5434 LOAD_IMGLIB_FN (library
, png_read_info
);
5435 LOAD_IMGLIB_FN (library
, png_get_IHDR
);
5436 LOAD_IMGLIB_FN (library
, png_get_valid
);
5437 LOAD_IMGLIB_FN (library
, png_set_strip_16
);
5438 LOAD_IMGLIB_FN (library
, png_set_expand
);
5439 LOAD_IMGLIB_FN (library
, png_set_gray_to_rgb
);
5440 LOAD_IMGLIB_FN (library
, png_set_background
);
5441 LOAD_IMGLIB_FN (library
, png_get_bKGD
);
5442 LOAD_IMGLIB_FN (library
, png_read_update_info
);
5443 LOAD_IMGLIB_FN (library
, png_get_channels
);
5444 LOAD_IMGLIB_FN (library
, png_get_rowbytes
);
5445 LOAD_IMGLIB_FN (library
, png_read_image
);
5446 LOAD_IMGLIB_FN (library
, png_read_end
);
5447 LOAD_IMGLIB_FN (library
, png_error
);
5449 #if (PNG_LIBPNG_VER >= 10500)
5450 LOAD_IMGLIB_FN (library
, png_longjmp
);
5451 LOAD_IMGLIB_FN (library
, png_set_longjmp_fn
);
5452 #endif /* libpng version >= 1.5 */
5458 #define fn_png_get_io_ptr png_get_io_ptr
5459 #define fn_png_sig_cmp png_sig_cmp
5460 #define fn_png_create_read_struct png_create_read_struct
5461 #define fn_png_create_info_struct png_create_info_struct
5462 #define fn_png_destroy_read_struct png_destroy_read_struct
5463 #define fn_png_set_read_fn png_set_read_fn
5464 #define fn_png_set_sig_bytes png_set_sig_bytes
5465 #define fn_png_read_info png_read_info
5466 #define fn_png_get_IHDR png_get_IHDR
5467 #define fn_png_get_valid png_get_valid
5468 #define fn_png_set_strip_16 png_set_strip_16
5469 #define fn_png_set_expand png_set_expand
5470 #define fn_png_set_gray_to_rgb png_set_gray_to_rgb
5471 #define fn_png_set_background png_set_background
5472 #define fn_png_get_bKGD png_get_bKGD
5473 #define fn_png_read_update_info png_read_update_info
5474 #define fn_png_get_channels png_get_channels
5475 #define fn_png_get_rowbytes png_get_rowbytes
5476 #define fn_png_read_image png_read_image
5477 #define fn_png_read_end png_read_end
5478 #define fn_png_error png_error
5480 #if (PNG_LIBPNG_VER >= 10500)
5481 #define fn_png_longjmp png_longjmp
5482 #define fn_png_set_longjmp_fn png_set_longjmp_fn
5483 #endif /* libpng version >= 1.5 */
5485 #endif /* HAVE_NTGUI */
5488 #if (PNG_LIBPNG_VER < 10500)
5489 #define PNG_LONGJMP(ptr) (longjmp ((ptr)->jmpbuf, 1))
5490 #define PNG_JMPBUF(ptr) ((ptr)->jmpbuf)
5492 /* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908) */
5493 #define PNG_LONGJMP(ptr) (fn_png_longjmp ((ptr), 1))
5494 #define PNG_JMPBUF(ptr) \
5495 (*fn_png_set_longjmp_fn((ptr), longjmp, sizeof (jmp_buf)))
5498 /* Error and warning handlers installed when the PNG library
5501 static void my_png_error (png_struct
*, const char *) NO_RETURN
;
5503 my_png_error (png_struct
*png_ptr
, const char *msg
)
5505 xassert (png_ptr
!= NULL
);
5506 /* Avoid compiler warning about deprecated direct access to
5507 png_ptr's fields in libpng versions 1.4.x. */
5508 image_error ("PNG error: %s", build_string (msg
), Qnil
);
5509 PNG_LONGJMP (png_ptr
);
5514 my_png_warning (png_struct
*png_ptr
, const char *msg
)
5516 xassert (png_ptr
!= NULL
);
5517 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
5520 /* Memory source for PNG decoding. */
5522 struct png_memory_storage
5524 unsigned char *bytes
; /* The data */
5525 size_t len
; /* How big is it? */
5526 int index
; /* Where are we? */
5530 /* Function set as reader function when reading PNG image from memory.
5531 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5532 bytes from the input to DATA. */
5535 png_read_from_memory (png_structp png_ptr
, png_bytep data
, png_size_t length
)
5537 struct png_memory_storage
*tbr
5538 = (struct png_memory_storage
*) fn_png_get_io_ptr (png_ptr
);
5540 if (length
> tbr
->len
- tbr
->index
)
5541 fn_png_error (png_ptr
, "Read error");
5543 memcpy (data
, tbr
->bytes
+ tbr
->index
, length
);
5544 tbr
->index
= tbr
->index
+ length
;
5548 /* Function set as reader function when reading PNG image from a file.
5549 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5550 bytes from the input to DATA. */
5553 png_read_from_file (png_structp png_ptr
, png_bytep data
, png_size_t length
)
5555 FILE *fp
= (FILE *) fn_png_get_io_ptr (png_ptr
);
5557 if (fread (data
, 1, length
, fp
) < length
)
5558 fn_png_error (png_ptr
, "Read error");
5562 /* Load PNG image IMG for use on frame F. Value is non-zero if
5566 png_load (struct frame
*f
, struct image
*img
)
5568 Lisp_Object file
, specified_file
;
5569 Lisp_Object specified_data
;
5571 XImagePtr ximg
, mask_img
= NULL
;
5572 png_struct
*png_ptr
= NULL
;
5573 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
5574 FILE *volatile fp
= NULL
;
5576 png_byte
* volatile pixels
= NULL
;
5577 png_byte
** volatile rows
= NULL
;
5578 png_uint_32 width
, height
;
5579 int bit_depth
, color_type
, interlace_type
;
5581 png_uint_32 row_bytes
;
5583 struct png_memory_storage tbr
; /* Data to be read */
5585 /* Find out what file to load. */
5586 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5587 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5589 if (NILP (specified_data
))
5591 file
= x_find_image_file (specified_file
);
5592 if (!STRINGP (file
))
5594 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5598 /* Open the image file. */
5599 fp
= fopen (SSDATA (file
), "rb");
5602 image_error ("Cannot open image file `%s'", file
, Qnil
);
5606 /* Check PNG signature. */
5607 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
5608 || fn_png_sig_cmp (sig
, 0, sizeof sig
))
5610 image_error ("Not a PNG file: `%s'", file
, Qnil
);
5617 if (!STRINGP (specified_data
))
5619 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
5623 /* Read from memory. */
5624 tbr
.bytes
= SDATA (specified_data
);
5625 tbr
.len
= SBYTES (specified_data
);
5628 /* Check PNG signature. */
5629 if (tbr
.len
< sizeof sig
5630 || fn_png_sig_cmp (tbr
.bytes
, 0, sizeof sig
))
5632 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
5636 /* Need to skip past the signature. */
5637 tbr
.bytes
+= sizeof (sig
);
5640 /* Initialize read and info structs for PNG lib. */
5641 png_ptr
= fn_png_create_read_struct (PNG_LIBPNG_VER_STRING
,
5646 if (fp
) fclose (fp
);
5650 info_ptr
= fn_png_create_info_struct (png_ptr
);
5653 fn_png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
5654 if (fp
) fclose (fp
);
5658 end_info
= fn_png_create_info_struct (png_ptr
);
5661 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
5662 if (fp
) fclose (fp
);
5666 /* Set error jump-back. We come back here when the PNG library
5667 detects an error. */
5668 if (setjmp (PNG_JMPBUF (png_ptr
)))
5672 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
5675 if (fp
) fclose (fp
);
5679 /* Read image info. */
5680 if (!NILP (specified_data
))
5681 fn_png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
5683 fn_png_set_read_fn (png_ptr
, (void *) fp
, png_read_from_file
);
5685 fn_png_set_sig_bytes (png_ptr
, sizeof sig
);
5686 fn_png_read_info (png_ptr
, info_ptr
);
5687 fn_png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
5688 &interlace_type
, NULL
, NULL
);
5690 if (!check_image_size (f
, width
, height
))
5692 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
5695 /* If image contains simply transparency data, we prefer to
5696 construct a clipping mask. */
5697 if (fn_png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
5702 /* This function is easier to write if we only have to handle
5703 one data format: RGB or RGBA with 8 bits per channel. Let's
5704 transform other formats into that format. */
5706 /* Strip more than 8 bits per channel. */
5707 if (bit_depth
== 16)
5708 fn_png_set_strip_16 (png_ptr
);
5710 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
5712 fn_png_set_expand (png_ptr
);
5714 /* Convert grayscale images to RGB. */
5715 if (color_type
== PNG_COLOR_TYPE_GRAY
5716 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
5717 fn_png_set_gray_to_rgb (png_ptr
);
5719 /* Handle alpha channel by combining the image with a background
5720 color. Do this only if a real alpha channel is supplied. For
5721 simple transparency, we prefer a clipping mask. */
5724 /* png_color_16 *image_bg; */
5725 Lisp_Object specified_bg
5726 = image_spec_value (img
->spec
, QCbackground
, NULL
);
5727 int shift
= (bit_depth
== 16) ? 0 : 8;
5729 if (STRINGP (specified_bg
))
5730 /* The user specified `:background', use that. */
5733 if (x_defined_color (f
, SSDATA (specified_bg
), &color
, 0))
5735 png_color_16 user_bg
;
5737 memset (&user_bg
, 0, sizeof user_bg
);
5738 user_bg
.red
= color
.red
>> shift
;
5739 user_bg
.green
= color
.green
>> shift
;
5740 user_bg
.blue
= color
.blue
>> shift
;
5742 fn_png_set_background (png_ptr
, &user_bg
,
5743 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
5748 /* We use the current frame background, ignoring any default
5749 background color set by the image. */
5750 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
5752 png_color_16 frame_background
;
5754 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
5755 x_query_color (f
, &color
);
5757 memset (&frame_background
, 0, sizeof frame_background
);
5758 frame_background
.red
= color
.red
>> shift
;
5759 frame_background
.green
= color
.green
>> shift
;
5760 frame_background
.blue
= color
.blue
>> shift
;
5761 #endif /* HAVE_X_WINDOWS */
5763 fn_png_set_background (png_ptr
, &frame_background
,
5764 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
5768 /* Update info structure. */
5769 fn_png_read_update_info (png_ptr
, info_ptr
);
5771 /* Get number of channels. Valid values are 1 for grayscale images
5772 and images with a palette, 2 for grayscale images with transparency
5773 information (alpha channel), 3 for RGB images, and 4 for RGB
5774 images with alpha channel, i.e. RGBA. If conversions above were
5775 sufficient we should only have 3 or 4 channels here. */
5776 channels
= fn_png_get_channels (png_ptr
, info_ptr
);
5777 xassert (channels
== 3 || channels
== 4);
5779 /* Number of bytes needed for one row of the image. */
5780 row_bytes
= fn_png_get_rowbytes (png_ptr
, info_ptr
);
5782 /* Allocate memory for the image. */
5783 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
5784 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
5785 for (i
= 0; i
< height
; ++i
)
5786 rows
[i
] = pixels
+ i
* row_bytes
;
5788 /* Read the entire image. */
5789 fn_png_read_image (png_ptr
, rows
);
5790 fn_png_read_end (png_ptr
, info_ptr
);
5797 /* Create the X image and pixmap. */
5798 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
5802 /* Create an image and pixmap serving as mask if the PNG image
5803 contains an alpha channel. */
5806 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
5807 &mask_img
, &img
->mask
))
5809 x_destroy_x_image (ximg
);
5810 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
5811 img
->pixmap
= NO_PIXMAP
;
5815 /* Fill the X image and mask from PNG data. */
5816 init_color_table ();
5818 for (y
= 0; y
< height
; ++y
)
5820 png_byte
*p
= rows
[y
];
5822 for (x
= 0; x
< width
; ++x
)
5829 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
5830 /* An alpha channel, aka mask channel, associates variable
5831 transparency with an image. Where other image formats
5832 support binary transparency---fully transparent or fully
5833 opaque---PNG allows up to 254 levels of partial transparency.
5834 The PNG library implements partial transparency by combining
5835 the image with a specified background color.
5837 I'm not sure how to handle this here nicely: because the
5838 background on which the image is displayed may change, for
5839 real alpha channel support, it would be necessary to create
5840 a new image for each possible background.
5842 What I'm doing now is that a mask is created if we have
5843 boolean transparency information. Otherwise I'm using
5844 the frame's background color to combine the image with. */
5849 XPutPixel (mask_img
, x
, y
, *p
> 0 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
);
5855 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
5856 /* Set IMG's background color from the PNG image, unless the user
5860 if (fn_png_get_bKGD (png_ptr
, info_ptr
, &bg
))
5862 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
5863 img
->background_valid
= 1;
5867 #ifdef COLOR_TABLE_SUPPORT
5868 /* Remember colors allocated for this image. */
5869 img
->colors
= colors_in_color_table (&img
->ncolors
);
5870 free_color_table ();
5871 #endif /* COLOR_TABLE_SUPPORT */
5874 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
5879 img
->height
= height
;
5881 /* Maybe fill in the background field while we have ximg handy.
5882 Casting avoids a GCC warning. */
5883 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
5885 /* Put the image into the pixmap, then free the X image and its buffer. */
5886 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
5887 x_destroy_x_image (ximg
);
5889 /* Same for the mask. */
5892 /* Fill in the background_transparent field while we have the
5893 mask handy. Casting avoids a GCC warning. */
5894 image_background_transparent (img
, f
, (XImagePtr_or_DC
)mask_img
);
5896 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
5897 x_destroy_x_image (mask_img
);
5903 #else /* HAVE_PNG */
5907 png_load (struct frame
*f
, struct image
*img
)
5909 return ns_load_image(f
, img
,
5910 image_spec_value (img
->spec
, QCfile
, NULL
),
5911 image_spec_value (img
->spec
, QCdata
, NULL
));
5913 #endif /* HAVE_NS */
5916 #endif /* !HAVE_PNG */
5920 /***********************************************************************
5922 ***********************************************************************/
5924 #if defined (HAVE_JPEG) || defined (HAVE_NS)
5926 static int jpeg_image_p (Lisp_Object object
);
5927 static int jpeg_load (struct frame
*f
, struct image
*img
);
5929 /* The symbol `jpeg' identifying images of this type. */
5931 static Lisp_Object Qjpeg
;
5933 /* Indices of image specification fields in gs_format, below. */
5935 enum jpeg_keyword_index
5944 JPEG_HEURISTIC_MASK
,
5950 /* Vector of image_keyword structures describing the format
5951 of valid user-defined image specifications. */
5953 static const struct image_keyword jpeg_format
[JPEG_LAST
] =
5955 {":type", IMAGE_SYMBOL_VALUE
, 1},
5956 {":data", IMAGE_STRING_VALUE
, 0},
5957 {":file", IMAGE_STRING_VALUE
, 0},
5958 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5959 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5960 {":relief", IMAGE_INTEGER_VALUE
, 0},
5961 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5962 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5963 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5964 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
5967 /* Structure describing the image type `jpeg'. */
5969 static struct image_type jpeg_type
=
5978 /* Return non-zero if OBJECT is a valid JPEG image specification. */
5981 jpeg_image_p (Lisp_Object object
)
5983 struct image_keyword fmt
[JPEG_LAST
];
5985 memcpy (fmt
, jpeg_format
, sizeof fmt
);
5987 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
5990 /* Must specify either the :data or :file keyword. */
5991 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
5994 #endif /* HAVE_JPEG || HAVE_NS */
5998 /* Work around a warning about HAVE_STDLIB_H being redefined in
6000 #ifdef HAVE_STDLIB_H
6001 #undef HAVE_STDLIB_H
6002 #endif /* HAVE_STLIB_H */
6004 #if defined (HAVE_NTGUI) && !defined (__WIN32__)
6005 /* In older releases of the jpeg library, jpeglib.h will define boolean
6006 differently depending on __WIN32__, so make sure it is defined. */
6010 #include <jpeglib.h>
6013 #ifdef HAVE_STLIB_H_1
6014 #define HAVE_STDLIB_H 1
6019 /* JPEG library details. */
6020 DEF_IMGLIB_FN (void, jpeg_CreateDecompress
, (j_decompress_ptr
, int, size_t));
6021 DEF_IMGLIB_FN (boolean
, jpeg_start_decompress
, (j_decompress_ptr
));
6022 DEF_IMGLIB_FN (boolean
, jpeg_finish_decompress
, (j_decompress_ptr
));
6023 DEF_IMGLIB_FN (void, jpeg_destroy_decompress
, (j_decompress_ptr
));
6024 DEF_IMGLIB_FN (int, jpeg_read_header
, (j_decompress_ptr
, boolean
));
6025 DEF_IMGLIB_FN (JDIMENSION
, jpeg_read_scanlines
, (j_decompress_ptr
, JSAMPARRAY
, JDIMENSION
));
6026 DEF_IMGLIB_FN (struct jpeg_error_mgr
*, jpeg_std_error
, (struct jpeg_error_mgr
*));
6027 DEF_IMGLIB_FN (boolean
, jpeg_resync_to_restart
, (j_decompress_ptr
, int));
6030 init_jpeg_functions (Lisp_Object libraries
)
6034 if (!(library
= w32_delayed_load (libraries
, Qjpeg
)))
6037 LOAD_IMGLIB_FN (library
, jpeg_finish_decompress
);
6038 LOAD_IMGLIB_FN (library
, jpeg_read_scanlines
);
6039 LOAD_IMGLIB_FN (library
, jpeg_start_decompress
);
6040 LOAD_IMGLIB_FN (library
, jpeg_read_header
);
6041 LOAD_IMGLIB_FN (library
, jpeg_CreateDecompress
);
6042 LOAD_IMGLIB_FN (library
, jpeg_destroy_decompress
);
6043 LOAD_IMGLIB_FN (library
, jpeg_std_error
);
6044 LOAD_IMGLIB_FN (library
, jpeg_resync_to_restart
);
6048 /* Wrapper since we can't directly assign the function pointer
6049 to another function pointer that was declared more completely easily. */
6051 jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo
, int desired
)
6053 return fn_jpeg_resync_to_restart (cinfo
, desired
);
6058 #define fn_jpeg_CreateDecompress(a,b,c) jpeg_create_decompress(a)
6059 #define fn_jpeg_start_decompress jpeg_start_decompress
6060 #define fn_jpeg_finish_decompress jpeg_finish_decompress
6061 #define fn_jpeg_destroy_decompress jpeg_destroy_decompress
6062 #define fn_jpeg_read_header jpeg_read_header
6063 #define fn_jpeg_read_scanlines jpeg_read_scanlines
6064 #define fn_jpeg_std_error jpeg_std_error
6065 #define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart
6067 #endif /* HAVE_NTGUI */
6069 struct my_jpeg_error_mgr
6071 struct jpeg_error_mgr pub
;
6072 jmp_buf setjmp_buffer
;
6076 static void my_error_exit (j_common_ptr
) NO_RETURN
;
6078 my_error_exit (j_common_ptr cinfo
)
6080 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
6081 longjmp (mgr
->setjmp_buffer
, 1);
6085 /* Init source method for JPEG data source manager. Called by
6086 jpeg_read_header() before any data is actually read. See
6087 libjpeg.doc from the JPEG lib distribution. */
6090 our_common_init_source (j_decompress_ptr cinfo
)
6095 /* Method to terminate data source. Called by
6096 jpeg_finish_decompress() after all data has been processed. */
6099 our_common_term_source (j_decompress_ptr cinfo
)
6104 /* Fill input buffer method for JPEG data source manager. Called
6105 whenever more data is needed. We read the whole image in one step,
6106 so this only adds a fake end of input marker at the end. */
6108 static JOCTET our_memory_buffer
[2];
6111 our_memory_fill_input_buffer (j_decompress_ptr cinfo
)
6113 /* Insert a fake EOI marker. */
6114 struct jpeg_source_mgr
*src
= cinfo
->src
;
6116 our_memory_buffer
[0] = (JOCTET
) 0xFF;
6117 our_memory_buffer
[1] = (JOCTET
) JPEG_EOI
;
6119 src
->next_input_byte
= our_memory_buffer
;
6120 src
->bytes_in_buffer
= 2;
6125 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6126 is the JPEG data source manager. */
6129 our_memory_skip_input_data (j_decompress_ptr cinfo
, long int num_bytes
)
6131 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6135 if (num_bytes
> src
->bytes_in_buffer
)
6136 ERREXIT (cinfo
, JERR_INPUT_EOF
);
6138 src
->bytes_in_buffer
-= num_bytes
;
6139 src
->next_input_byte
+= num_bytes
;
6144 /* Set up the JPEG lib for reading an image from DATA which contains
6145 LEN bytes. CINFO is the decompression info structure created for
6146 reading the image. */
6149 jpeg_memory_src (j_decompress_ptr cinfo
, JOCTET
*data
, unsigned int len
)
6151 struct jpeg_source_mgr
*src
;
6153 if (cinfo
->src
== NULL
)
6155 /* First time for this JPEG object? */
6156 cinfo
->src
= (struct jpeg_source_mgr
*)
6157 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6158 sizeof (struct jpeg_source_mgr
));
6159 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6160 src
->next_input_byte
= data
;
6163 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6164 src
->init_source
= our_common_init_source
;
6165 src
->fill_input_buffer
= our_memory_fill_input_buffer
;
6166 src
->skip_input_data
= our_memory_skip_input_data
;
6167 src
->resync_to_restart
= jpeg_resync_to_restart_wrapper
; /* Use default method. */
6168 src
->term_source
= our_common_term_source
;
6169 src
->bytes_in_buffer
= len
;
6170 src
->next_input_byte
= data
;
6174 struct jpeg_stdio_mgr
6176 struct jpeg_source_mgr mgr
;
6183 /* Size of buffer to read JPEG from file.
6184 Not too big, as we want to use alloc_small. */
6185 #define JPEG_STDIO_BUFFER_SIZE 8192
6188 /* Fill input buffer method for JPEG data source manager. Called
6189 whenever more data is needed. The data is read from a FILE *. */
6192 our_stdio_fill_input_buffer (j_decompress_ptr cinfo
)
6194 struct jpeg_stdio_mgr
*src
;
6196 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6201 bytes
= fread (src
->buffer
, 1, JPEG_STDIO_BUFFER_SIZE
, src
->file
);
6203 src
->mgr
.bytes_in_buffer
= bytes
;
6206 WARNMS (cinfo
, JWRN_JPEG_EOF
);
6208 src
->buffer
[0] = (JOCTET
) 0xFF;
6209 src
->buffer
[1] = (JOCTET
) JPEG_EOI
;
6210 src
->mgr
.bytes_in_buffer
= 2;
6212 src
->mgr
.next_input_byte
= src
->buffer
;
6219 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6220 is the JPEG data source manager. */
6223 our_stdio_skip_input_data (j_decompress_ptr cinfo
, long int num_bytes
)
6225 struct jpeg_stdio_mgr
*src
;
6226 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6228 while (num_bytes
> 0 && !src
->finished
)
6230 if (num_bytes
<= src
->mgr
.bytes_in_buffer
)
6232 src
->mgr
.bytes_in_buffer
-= num_bytes
;
6233 src
->mgr
.next_input_byte
+= num_bytes
;
6238 num_bytes
-= src
->mgr
.bytes_in_buffer
;
6239 src
->mgr
.bytes_in_buffer
= 0;
6240 src
->mgr
.next_input_byte
= NULL
;
6242 our_stdio_fill_input_buffer (cinfo
);
6248 /* Set up the JPEG lib for reading an image from a FILE *.
6249 CINFO is the decompression info structure created for
6250 reading the image. */
6253 jpeg_file_src (j_decompress_ptr cinfo
, FILE *fp
)
6255 struct jpeg_stdio_mgr
*src
;
6257 if (cinfo
->src
!= NULL
)
6258 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6261 /* First time for this JPEG object? */
6262 cinfo
->src
= (struct jpeg_source_mgr
*)
6263 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6264 sizeof (struct jpeg_stdio_mgr
));
6265 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6266 src
->buffer
= (JOCTET
*)
6267 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6268 JPEG_STDIO_BUFFER_SIZE
);
6273 src
->mgr
.init_source
= our_common_init_source
;
6274 src
->mgr
.fill_input_buffer
= our_stdio_fill_input_buffer
;
6275 src
->mgr
.skip_input_data
= our_stdio_skip_input_data
;
6276 src
->mgr
.resync_to_restart
= jpeg_resync_to_restart_wrapper
; /* Use default method. */
6277 src
->mgr
.term_source
= our_common_term_source
;
6278 src
->mgr
.bytes_in_buffer
= 0;
6279 src
->mgr
.next_input_byte
= NULL
;
6283 /* Load image IMG for use on frame F. Patterned after example.c
6284 from the JPEG lib. */
6287 jpeg_load (struct frame
*f
, struct image
*img
)
6289 struct jpeg_decompress_struct cinfo
;
6290 struct my_jpeg_error_mgr mgr
;
6291 Lisp_Object file
, specified_file
;
6292 Lisp_Object specified_data
;
6293 FILE * volatile fp
= NULL
;
6295 int row_stride
, x
, y
;
6296 XImagePtr ximg
= NULL
;
6298 unsigned long *colors
;
6301 /* Open the JPEG file. */
6302 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6303 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6305 if (NILP (specified_data
))
6307 file
= x_find_image_file (specified_file
);
6308 if (!STRINGP (file
))
6310 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6314 fp
= fopen (SSDATA (file
), "rb");
6317 image_error ("Cannot open `%s'", file
, Qnil
);
6321 else if (!STRINGP (specified_data
))
6323 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
6327 /* Customize libjpeg's error handling to call my_error_exit when an
6328 error is detected. This function will perform a longjmp. */
6329 cinfo
.err
= fn_jpeg_std_error (&mgr
.pub
);
6330 mgr
.pub
.error_exit
= my_error_exit
;
6332 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
6336 /* Called from my_error_exit. Display a JPEG error. */
6337 char buf
[JMSG_LENGTH_MAX
];
6338 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buf
);
6339 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
6340 build_string (buf
));
6343 /* Close the input file and destroy the JPEG object. */
6345 fclose ((FILE *) fp
);
6346 fn_jpeg_destroy_decompress (&cinfo
);
6348 /* If we already have an XImage, free that. */
6349 x_destroy_x_image (ximg
);
6351 /* Free pixmap and colors. */
6352 x_clear_image (f
, img
);
6356 /* Create the JPEG decompression object. Let it read from fp.
6357 Read the JPEG image header. */
6358 fn_jpeg_CreateDecompress (&cinfo
, JPEG_LIB_VERSION
, sizeof (cinfo
));
6360 if (NILP (specified_data
))
6361 jpeg_file_src (&cinfo
, (FILE *) fp
);
6363 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
6364 SBYTES (specified_data
));
6366 fn_jpeg_read_header (&cinfo
, 1);
6368 /* Customize decompression so that color quantization will be used.
6369 Start decompression. */
6370 cinfo
.quantize_colors
= 1;
6371 fn_jpeg_start_decompress (&cinfo
);
6372 width
= img
->width
= cinfo
.output_width
;
6373 height
= img
->height
= cinfo
.output_height
;
6375 if (!check_image_size (f
, width
, height
))
6377 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
6378 longjmp (mgr
.setjmp_buffer
, 2);
6381 /* Create X image and pixmap. */
6382 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
6383 longjmp (mgr
.setjmp_buffer
, 2);
6385 /* Allocate colors. When color quantization is used,
6386 cinfo.actual_number_of_colors has been set with the number of
6387 colors generated, and cinfo.colormap is a two-dimensional array
6388 of color indices in the range 0..cinfo.actual_number_of_colors.
6389 No more than 255 colors will be generated. */
6393 if (cinfo
.out_color_components
> 2)
6394 ir
= 0, ig
= 1, ib
= 2;
6395 else if (cinfo
.out_color_components
> 1)
6396 ir
= 0, ig
= 1, ib
= 0;
6398 ir
= 0, ig
= 0, ib
= 0;
6400 /* Use the color table mechanism because it handles colors that
6401 cannot be allocated nicely. Such colors will be replaced with
6402 a default color, and we don't have to care about which colors
6403 can be freed safely, and which can't. */
6404 init_color_table ();
6405 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
6408 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
6410 /* Multiply RGB values with 255 because X expects RGB values
6411 in the range 0..0xffff. */
6412 int r
= cinfo
.colormap
[ir
][i
] << 8;
6413 int g
= cinfo
.colormap
[ig
][i
] << 8;
6414 int b
= cinfo
.colormap
[ib
][i
] << 8;
6415 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
6418 #ifdef COLOR_TABLE_SUPPORT
6419 /* Remember those colors actually allocated. */
6420 img
->colors
= colors_in_color_table (&img
->ncolors
);
6421 free_color_table ();
6422 #endif /* COLOR_TABLE_SUPPORT */
6426 row_stride
= width
* cinfo
.output_components
;
6427 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
6429 for (y
= 0; y
< height
; ++y
)
6431 fn_jpeg_read_scanlines (&cinfo
, buffer
, 1);
6432 for (x
= 0; x
< cinfo
.output_width
; ++x
)
6433 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
6437 fn_jpeg_finish_decompress (&cinfo
);
6438 fn_jpeg_destroy_decompress (&cinfo
);
6440 fclose ((FILE *) fp
);
6442 /* Maybe fill in the background field while we have ximg handy. */
6443 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6444 /* Casting avoids a GCC warning. */
6445 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6447 /* Put the image into the pixmap. */
6448 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6449 x_destroy_x_image (ximg
);
6453 #else /* HAVE_JPEG */
6457 jpeg_load (struct frame
*f
, struct image
*img
)
6459 return ns_load_image (f
, img
,
6460 image_spec_value (img
->spec
, QCfile
, NULL
),
6461 image_spec_value (img
->spec
, QCdata
, NULL
));
6463 #endif /* HAVE_NS */
6465 #endif /* !HAVE_JPEG */
6469 /***********************************************************************
6471 ***********************************************************************/
6473 #if defined (HAVE_TIFF) || defined (HAVE_NS)
6475 static int tiff_image_p (Lisp_Object object
);
6476 static int tiff_load (struct frame
*f
, struct image
*img
);
6478 /* The symbol `tiff' identifying images of this type. */
6480 static Lisp_Object Qtiff
;
6482 /* Indices of image specification fields in tiff_format, below. */
6484 enum tiff_keyword_index
6493 TIFF_HEURISTIC_MASK
,
6500 /* Vector of image_keyword structures describing the format
6501 of valid user-defined image specifications. */
6503 static const struct image_keyword tiff_format
[TIFF_LAST
] =
6505 {":type", IMAGE_SYMBOL_VALUE
, 1},
6506 {":data", IMAGE_STRING_VALUE
, 0},
6507 {":file", IMAGE_STRING_VALUE
, 0},
6508 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6509 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6510 {":relief", IMAGE_INTEGER_VALUE
, 0},
6511 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6512 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6513 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6514 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
6515 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0}
6518 /* Structure describing the image type `tiff'. */
6520 static struct image_type tiff_type
=
6529 /* Return non-zero if OBJECT is a valid TIFF image specification. */
6532 tiff_image_p (Lisp_Object object
)
6534 struct image_keyword fmt
[TIFF_LAST
];
6535 memcpy (fmt
, tiff_format
, sizeof fmt
);
6537 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
6540 /* Must specify either the :data or :file keyword. */
6541 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
6544 #endif /* HAVE_TIFF || HAVE_NS */
6552 /* TIFF library details. */
6553 DEF_IMGLIB_FN (TIFFErrorHandler
, TIFFSetErrorHandler
, (TIFFErrorHandler
));
6554 DEF_IMGLIB_FN (TIFFErrorHandler
, TIFFSetWarningHandler
, (TIFFErrorHandler
));
6555 DEF_IMGLIB_FN (TIFF
*, TIFFOpen
, (const char *, const char *));
6556 DEF_IMGLIB_FN (TIFF
*, TIFFClientOpen
, (const char *, const char *, thandle_t
,
6557 TIFFReadWriteProc
, TIFFReadWriteProc
,
6558 TIFFSeekProc
, TIFFCloseProc
, TIFFSizeProc
,
6559 TIFFMapFileProc
, TIFFUnmapFileProc
));
6560 DEF_IMGLIB_FN (int, TIFFGetField
, (TIFF
*, ttag_t
, ...));
6561 DEF_IMGLIB_FN (int, TIFFReadRGBAImage
, (TIFF
*, uint32
, uint32
, uint32
*, int));
6562 DEF_IMGLIB_FN (void, TIFFClose
, (TIFF
*));
6563 DEF_IMGLIB_FN (int, TIFFSetDirectory
, (TIFF
*, tdir_t
));
6566 init_tiff_functions (Lisp_Object libraries
)
6570 if (!(library
= w32_delayed_load (libraries
, Qtiff
)))
6573 LOAD_IMGLIB_FN (library
, TIFFSetErrorHandler
);
6574 LOAD_IMGLIB_FN (library
, TIFFSetWarningHandler
);
6575 LOAD_IMGLIB_FN (library
, TIFFOpen
);
6576 LOAD_IMGLIB_FN (library
, TIFFClientOpen
);
6577 LOAD_IMGLIB_FN (library
, TIFFGetField
);
6578 LOAD_IMGLIB_FN (library
, TIFFReadRGBAImage
);
6579 LOAD_IMGLIB_FN (library
, TIFFClose
);
6580 LOAD_IMGLIB_FN (library
, TIFFSetDirectory
);
6586 #define fn_TIFFSetErrorHandler TIFFSetErrorHandler
6587 #define fn_TIFFSetWarningHandler TIFFSetWarningHandler
6588 #define fn_TIFFOpen TIFFOpen
6589 #define fn_TIFFClientOpen TIFFClientOpen
6590 #define fn_TIFFGetField TIFFGetField
6591 #define fn_TIFFReadRGBAImage TIFFReadRGBAImage
6592 #define fn_TIFFClose TIFFClose
6593 #define fn_TIFFSetDirectory TIFFSetDirectory
6594 #endif /* HAVE_NTGUI */
6597 /* Reading from a memory buffer for TIFF images Based on the PNG
6598 memory source, but we have to provide a lot of extra functions.
6601 We really only need to implement read and seek, but I am not
6602 convinced that the TIFF library is smart enough not to destroy
6603 itself if we only hand it the function pointers we need to
6608 unsigned char *bytes
;
6615 tiff_read_from_memory (thandle_t data
, tdata_t buf
, tsize_t size
)
6617 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6619 if (size
> src
->len
- src
->index
)
6621 memcpy (buf
, src
->bytes
+ src
->index
, size
);
6627 tiff_write_from_memory (thandle_t data
, tdata_t buf
, tsize_t size
)
6633 tiff_seek_in_memory (thandle_t data
, toff_t off
, int whence
)
6635 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6640 case SEEK_SET
: /* Go from beginning of source. */
6644 case SEEK_END
: /* Go from end of source. */
6645 idx
= src
->len
+ off
;
6648 case SEEK_CUR
: /* Go from current position. */
6649 idx
= src
->index
+ off
;
6652 default: /* Invalid `whence'. */
6656 if (idx
> src
->len
|| idx
< 0)
6664 tiff_close_memory (thandle_t data
)
6671 tiff_mmap_memory (thandle_t data
, tdata_t
*pbase
, toff_t
*psize
)
6673 /* It is already _IN_ memory. */
6678 tiff_unmap_memory (thandle_t data
, tdata_t base
, toff_t size
)
6680 /* We don't need to do this. */
6684 tiff_size_of_memory (thandle_t data
)
6686 return ((tiff_memory_source
*) data
)->len
;
6690 static void tiff_error_handler (const char *, const char *, va_list)
6691 ATTRIBUTE_FORMAT_PRINTF (2, 0);
6693 tiff_error_handler (const char *title
, const char *format
, va_list ap
)
6698 len
= sprintf (buf
, "TIFF error: %s ", title
);
6699 vsprintf (buf
+ len
, format
, ap
);
6700 add_to_log (buf
, Qnil
, Qnil
);
6704 static void tiff_warning_handler (const char *, const char *, va_list)
6705 ATTRIBUTE_FORMAT_PRINTF (2, 0);
6707 tiff_warning_handler (const char *title
, const char *format
, va_list ap
)
6712 len
= sprintf (buf
, "TIFF warning: %s ", title
);
6713 vsprintf (buf
+ len
, format
, ap
);
6714 add_to_log (buf
, Qnil
, Qnil
);
6718 /* Load TIFF image IMG for use on frame F. Value is non-zero if
6722 tiff_load (struct frame
*f
, struct image
*img
)
6724 Lisp_Object file
, specified_file
;
6725 Lisp_Object specified_data
;
6727 int width
, height
, x
, y
, count
;
6731 tiff_memory_source memsrc
;
6734 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6735 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6737 fn_TIFFSetErrorHandler ((TIFFErrorHandler
) tiff_error_handler
);
6738 fn_TIFFSetWarningHandler ((TIFFErrorHandler
) tiff_warning_handler
);
6740 if (NILP (specified_data
))
6742 /* Read from a file */
6743 file
= x_find_image_file (specified_file
);
6744 if (!STRINGP (file
))
6746 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6750 /* Try to open the image file. */
6751 tiff
= fn_TIFFOpen (SSDATA (file
), "r");
6754 image_error ("Cannot open `%s'", file
, Qnil
);
6760 if (!STRINGP (specified_data
))
6762 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
6766 /* Memory source! */
6767 memsrc
.bytes
= SDATA (specified_data
);
6768 memsrc
.len
= SBYTES (specified_data
);
6771 tiff
= fn_TIFFClientOpen ("memory_source", "r", (thandle_t
)&memsrc
,
6772 (TIFFReadWriteProc
) tiff_read_from_memory
,
6773 (TIFFReadWriteProc
) tiff_write_from_memory
,
6774 tiff_seek_in_memory
,
6776 tiff_size_of_memory
,
6782 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
6787 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
6788 if (INTEGERP (image
))
6790 int ino
= XFASTINT (image
);
6791 if (!fn_TIFFSetDirectory (tiff
, ino
))
6793 image_error ("Invalid image number `%s' in image `%s'",
6795 fn_TIFFClose (tiff
);
6800 /* Get width and height of the image, and allocate a raster buffer
6801 of width x height 32-bit values. */
6802 fn_TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
6803 fn_TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
6805 if (!check_image_size (f
, width
, height
))
6807 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
6808 fn_TIFFClose (tiff
);
6812 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
6814 rc
= fn_TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
6816 /* Count the number of images in the file. */
6817 for (count
= 1; fn_TIFFSetDirectory (tiff
, count
); count
++)
6821 img
->lisp_data
= Fcons (Qcount
,
6822 Fcons (make_number (count
),
6825 fn_TIFFClose (tiff
);
6828 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
6833 /* Create the X image and pixmap. */
6834 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
6840 /* Initialize the color table. */
6841 init_color_table ();
6843 /* Process the pixel raster. Origin is in the lower-left corner. */
6844 for (y
= 0; y
< height
; ++y
)
6846 uint32
*row
= buf
+ y
* width
;
6848 for (x
= 0; x
< width
; ++x
)
6850 uint32 abgr
= row
[x
];
6851 int r
= TIFFGetR (abgr
) << 8;
6852 int g
= TIFFGetG (abgr
) << 8;
6853 int b
= TIFFGetB (abgr
) << 8;
6854 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
6858 #ifdef COLOR_TABLE_SUPPORT
6859 /* Remember the colors allocated for the image. Free the color table. */
6860 img
->colors
= colors_in_color_table (&img
->ncolors
);
6861 free_color_table ();
6862 #endif /* COLOR_TABLE_SUPPORT */
6865 img
->height
= height
;
6867 /* Maybe fill in the background field while we have ximg handy. */
6868 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6869 /* Casting avoids a GCC warning on W32. */
6870 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6872 /* Put the image into the pixmap, then free the X image and its buffer. */
6873 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6874 x_destroy_x_image (ximg
);
6880 #else /* HAVE_TIFF */
6884 tiff_load (struct frame
*f
, struct image
*img
)
6886 return ns_load_image (f
, img
,
6887 image_spec_value (img
->spec
, QCfile
, NULL
),
6888 image_spec_value (img
->spec
, QCdata
, NULL
));
6890 #endif /* HAVE_NS */
6892 #endif /* !HAVE_TIFF */
6896 /***********************************************************************
6898 ***********************************************************************/
6900 #if defined (HAVE_GIF) || defined (HAVE_NS)
6902 static int gif_image_p (Lisp_Object object
);
6903 static int gif_load (struct frame
*f
, struct image
*img
);
6904 static void gif_clear_image (struct frame
*f
, struct image
*img
);
6906 /* The symbol `gif' identifying images of this type. */
6908 static Lisp_Object Qgif
;
6910 /* Indices of image specification fields in gif_format, below. */
6912 enum gif_keyword_index
6928 /* Vector of image_keyword structures describing the format
6929 of valid user-defined image specifications. */
6931 static const struct image_keyword gif_format
[GIF_LAST
] =
6933 {":type", IMAGE_SYMBOL_VALUE
, 1},
6934 {":data", IMAGE_STRING_VALUE
, 0},
6935 {":file", IMAGE_STRING_VALUE
, 0},
6936 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6937 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6938 {":relief", IMAGE_INTEGER_VALUE
, 0},
6939 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6940 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6941 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6942 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6943 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
6946 /* Structure describing the image type `gif'. */
6948 static struct image_type gif_type
=
6957 /* Free X resources of GIF image IMG which is used on frame F. */
6960 gif_clear_image (struct frame
*f
, struct image
*img
)
6962 img
->lisp_data
= Qnil
;
6963 x_clear_image (f
, img
);
6966 /* Return non-zero if OBJECT is a valid GIF image specification. */
6969 gif_image_p (Lisp_Object object
)
6971 struct image_keyword fmt
[GIF_LAST
];
6972 memcpy (fmt
, gif_format
, sizeof fmt
);
6974 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
6977 /* Must specify either the :data or :file keyword. */
6978 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
6981 #endif /* HAVE_GIF */
6985 #if defined (HAVE_NTGUI)
6986 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
6987 Undefine before redefining to avoid a preprocessor warning. */
6991 /* avoid conflict with QuickdrawText.h */
6992 #define DrawText gif_DrawText
6993 #include <gif_lib.h>
6996 #else /* HAVE_NTGUI */
6998 #include <gif_lib.h>
7000 #endif /* HAVE_NTGUI */
7005 /* GIF library details. */
7006 DEF_IMGLIB_FN (int, DGifCloseFile
, (GifFileType
*));
7007 DEF_IMGLIB_FN (int, DGifSlurp
, (GifFileType
*));
7008 DEF_IMGLIB_FN (GifFileType
*, DGifOpen
, (void *, InputFunc
));
7009 DEF_IMGLIB_FN (GifFileType
*, DGifOpenFileName
, (const char *));
7012 init_gif_functions (Lisp_Object libraries
)
7016 if (!(library
= w32_delayed_load (libraries
, Qgif
)))
7019 LOAD_IMGLIB_FN (library
, DGifCloseFile
);
7020 LOAD_IMGLIB_FN (library
, DGifSlurp
);
7021 LOAD_IMGLIB_FN (library
, DGifOpen
);
7022 LOAD_IMGLIB_FN (library
, DGifOpenFileName
);
7028 #define fn_DGifCloseFile DGifCloseFile
7029 #define fn_DGifSlurp DGifSlurp
7030 #define fn_DGifOpen DGifOpen
7031 #define fn_DGifOpenFileName DGifOpenFileName
7033 #endif /* HAVE_NTGUI */
7035 /* Reading a GIF image from memory
7036 Based on the PNG memory stuff to a certain extent. */
7040 unsigned char *bytes
;
7046 /* Make the current memory source available to gif_read_from_memory.
7047 It's done this way because not all versions of libungif support
7048 a UserData field in the GifFileType structure. */
7049 static gif_memory_source
*current_gif_memory_src
;
7052 gif_read_from_memory (GifFileType
*file
, GifByteType
*buf
, int len
)
7054 gif_memory_source
*src
= current_gif_memory_src
;
7056 if (len
> src
->len
- src
->index
)
7059 memcpy (buf
, src
->bytes
+ src
->index
, len
);
7065 /* Load GIF image IMG for use on frame F. Value is non-zero if
7068 static const int interlace_start
[] = {0, 4, 2, 1};
7069 static const int interlace_increment
[] = {8, 8, 4, 2};
7071 #define GIF_LOCAL_DESCRIPTOR_EXTENSION 249
7074 gif_load (struct frame
*f
, struct image
*img
)
7077 int rc
, width
, height
, x
, y
, i
, j
;
7079 ColorMapObject
*gif_color_map
;
7080 unsigned long pixel_colors
[256];
7082 int image_height
, image_width
;
7083 gif_memory_source memsrc
;
7084 Lisp_Object specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
7085 Lisp_Object specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7086 Lisp_Object specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7087 unsigned long bgcolor
= 0;
7090 if (NILP (specified_data
))
7092 file
= x_find_image_file (specified_file
);
7093 if (!STRINGP (file
))
7095 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7099 /* Open the GIF file. */
7100 gif
= fn_DGifOpenFileName (SSDATA (file
));
7103 image_error ("Cannot open `%s'", file
, Qnil
);
7109 if (!STRINGP (specified_data
))
7111 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
7115 /* Read from memory! */
7116 current_gif_memory_src
= &memsrc
;
7117 memsrc
.bytes
= SDATA (specified_data
);
7118 memsrc
.len
= SBYTES (specified_data
);
7121 gif
= fn_DGifOpen (&memsrc
, gif_read_from_memory
);
7124 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
7129 /* Before reading entire contents, check the declared image size. */
7130 if (!check_image_size (f
, gif
->SWidth
, gif
->SHeight
))
7132 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7133 fn_DGifCloseFile (gif
);
7137 /* Read entire contents. */
7138 rc
= fn_DGifSlurp (gif
);
7139 if (rc
== GIF_ERROR
|| gif
->ImageCount
<= 0)
7141 image_error ("Error reading `%s'", img
->spec
, Qnil
);
7142 fn_DGifCloseFile (gif
);
7146 /* Which sub-image are we to display? */
7148 Lisp_Object image_number
= image_spec_value (img
->spec
, QCindex
, NULL
);
7149 idx
= INTEGERP (image_number
) ? XFASTINT (image_number
) : 0;
7150 if (idx
< 0 || idx
>= gif
->ImageCount
)
7152 image_error ("Invalid image number `%s' in image `%s'",
7153 image_number
, img
->spec
);
7154 fn_DGifCloseFile (gif
);
7159 img
->corners
[TOP_CORNER
] = gif
->SavedImages
[idx
].ImageDesc
.Top
;
7160 img
->corners
[LEFT_CORNER
] = gif
->SavedImages
[idx
].ImageDesc
.Left
;
7161 image_height
= gif
->SavedImages
[idx
].ImageDesc
.Height
;
7162 img
->corners
[BOT_CORNER
] = img
->corners
[TOP_CORNER
] + image_height
;
7163 image_width
= gif
->SavedImages
[idx
].ImageDesc
.Width
;
7164 img
->corners
[RIGHT_CORNER
] = img
->corners
[LEFT_CORNER
] + image_width
;
7166 width
= img
->width
= max (gif
->SWidth
,
7167 max (gif
->Image
.Left
+ gif
->Image
.Width
,
7168 img
->corners
[RIGHT_CORNER
]));
7169 height
= img
->height
= max (gif
->SHeight
,
7170 max (gif
->Image
.Top
+ gif
->Image
.Height
,
7171 img
->corners
[BOT_CORNER
]));
7173 if (!check_image_size (f
, width
, height
))
7175 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7176 fn_DGifCloseFile (gif
);
7180 /* Create the X image and pixmap. */
7181 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
7183 fn_DGifCloseFile (gif
);
7187 /* Clear the part of the screen image not covered by the image.
7188 Full animated GIF support requires more here (see the gif89 spec,
7189 disposal methods). Let's simply assume that the part not covered
7190 by a sub-image is in the frame's background color. */
7191 for (y
= 0; y
< img
->corners
[TOP_CORNER
]; ++y
)
7192 for (x
= 0; x
< width
; ++x
)
7193 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7195 for (y
= img
->corners
[BOT_CORNER
]; y
< height
; ++y
)
7196 for (x
= 0; x
< width
; ++x
)
7197 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7199 for (y
= img
->corners
[TOP_CORNER
]; y
< img
->corners
[BOT_CORNER
]; ++y
)
7201 for (x
= 0; x
< img
->corners
[LEFT_CORNER
]; ++x
)
7202 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7203 for (x
= img
->corners
[RIGHT_CORNER
]; x
< width
; ++x
)
7204 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7207 /* Read the GIF image into the X image. */
7209 /* FIXME: With the current implementation, loading an animated gif
7210 is quadratic in the number of animation frames, since each frame
7211 is a separate struct image. We must provide a way for a single
7212 gif_load call to construct and save all animation frames. */
7214 init_color_table ();
7215 if (STRINGP (specified_bg
))
7216 bgcolor
= x_alloc_image_color (f
, img
, specified_bg
,
7217 FRAME_BACKGROUND_PIXEL (f
));
7218 for (j
= 0; j
<= idx
; ++j
)
7220 /* We use a local variable `raster' here because RasterBits is a
7221 char *, which invites problems with bytes >= 0x80. */
7222 struct SavedImage
*subimage
= gif
->SavedImages
+ j
;
7223 unsigned char *raster
= (unsigned char *) subimage
->RasterBits
;
7224 int transparency_color_index
= -1;
7227 /* Find the Graphic Control Extension block for this sub-image.
7228 Extract the disposal method and transparency color. */
7229 for (i
= 0; i
< subimage
->ExtensionBlockCount
; i
++)
7231 ExtensionBlock
*extblock
= subimage
->ExtensionBlocks
+ i
;
7233 if ((extblock
->Function
== GIF_LOCAL_DESCRIPTOR_EXTENSION
)
7234 && extblock
->ByteCount
== 4
7235 && extblock
->Bytes
[0] & 1)
7237 /* From gif89a spec: 1 = "keep in place", 2 = "restore
7238 to background". Treat any other value like 2. */
7239 disposal
= (extblock
->Bytes
[0] >> 2) & 7;
7240 transparency_color_index
= (unsigned char) extblock
->Bytes
[3];
7245 /* We can't "keep in place" the first subimage. */
7249 /* Allocate subimage colors. */
7250 memset (pixel_colors
, 0, sizeof pixel_colors
);
7251 gif_color_map
= subimage
->ImageDesc
.ColorMap
;
7253 gif_color_map
= gif
->SColorMap
;
7256 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
7258 if (transparency_color_index
== i
)
7259 pixel_colors
[i
] = STRINGP (specified_bg
)
7260 ? bgcolor
: FRAME_BACKGROUND_PIXEL (f
);
7263 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
7264 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
7265 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
7266 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
7270 /* Apply the pixel values. */
7271 if (gif
->SavedImages
[j
].ImageDesc
.Interlace
)
7275 for (y
= 0, row
= interlace_start
[0], pass
= 0;
7277 y
++, row
+= interlace_increment
[pass
])
7279 if (row
>= image_height
)
7281 row
= interlace_start
[++pass
];
7282 while (row
>= image_height
)
7283 row
= interlace_start
[++pass
];
7286 for (x
= 0; x
< image_width
; x
++)
7288 int c
= raster
[y
* image_width
+ x
];
7289 if (transparency_color_index
!= c
|| disposal
!= 1)
7290 XPutPixel (ximg
, x
+ img
->corners
[LEFT_CORNER
],
7291 row
+ img
->corners
[TOP_CORNER
], pixel_colors
[c
]);
7297 for (y
= 0; y
< image_height
; ++y
)
7298 for (x
= 0; x
< image_width
; ++x
)
7300 int c
= raster
[y
* image_width
+ x
];
7301 if (transparency_color_index
!= c
|| disposal
!= 1)
7302 XPutPixel (ximg
, x
+ img
->corners
[LEFT_CORNER
],
7303 y
+ img
->corners
[TOP_CORNER
], pixel_colors
[c
]);
7308 #ifdef COLOR_TABLE_SUPPORT
7309 img
->colors
= colors_in_color_table (&img
->ncolors
);
7310 free_color_table ();
7311 #endif /* COLOR_TABLE_SUPPORT */
7313 /* Save GIF image extension data for `image-metadata'.
7314 Format is (count IMAGES extension-data (FUNCTION "BYTES" ...)). */
7315 img
->lisp_data
= Qnil
;
7316 if (gif
->SavedImages
[idx
].ExtensionBlockCount
> 0)
7318 unsigned int delay
= 0;
7319 ExtensionBlock
*ext
= gif
->SavedImages
[idx
].ExtensionBlocks
;
7320 for (i
= 0; i
< gif
->SavedImages
[idx
].ExtensionBlockCount
; i
++, ext
++)
7321 /* Append (... FUNCTION "BYTES") */
7324 = Fcons (make_number (ext
->Function
),
7325 Fcons (make_unibyte_string (ext
->Bytes
, ext
->ByteCount
),
7327 if (ext
->Function
== GIF_LOCAL_DESCRIPTOR_EXTENSION
7328 && ext
->ByteCount
== 4)
7330 delay
= ext
->Bytes
[2] << CHAR_BIT
;
7331 delay
|= ext
->Bytes
[1];
7334 img
->lisp_data
= Fcons (Qextension_data
,
7335 Fcons (img
->lisp_data
, Qnil
));
7339 Fcons (make_float (((double) delay
) * 0.01),
7343 if (gif
->ImageCount
> 1)
7344 img
->lisp_data
= Fcons (Qcount
,
7345 Fcons (make_number (gif
->ImageCount
),
7348 fn_DGifCloseFile (gif
);
7350 /* Maybe fill in the background field while we have ximg handy. */
7351 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7352 /* Casting avoids a GCC warning. */
7353 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
7355 /* Put the image into the pixmap, then free the X image and its buffer. */
7356 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7357 x_destroy_x_image (ximg
);
7362 #else /* !HAVE_GIF */
7366 gif_load (struct frame
*f
, struct image
*img
)
7368 return ns_load_image (f
, img
,
7369 image_spec_value (img
->spec
, QCfile
, NULL
),
7370 image_spec_value (img
->spec
, QCdata
, NULL
));
7372 #endif /* HAVE_NS */
7374 #endif /* HAVE_GIF */
7377 /***********************************************************************
7379 ***********************************************************************/
7380 #if defined (HAVE_IMAGEMAGICK)
7382 static Lisp_Object Qimagemagick
;
7384 static int imagemagick_image_p (Lisp_Object
);
7385 static int imagemagick_load (struct frame
*, struct image
*);
7386 static void imagemagick_clear_image (struct frame
*, struct image
*);
7388 /* Indices of image specification fields in imagemagick_format. */
7390 enum imagemagick_keyword_index
7398 IMAGEMAGICK_ALGORITHM
,
7399 IMAGEMAGICK_HEURISTIC_MASK
,
7401 IMAGEMAGICK_BACKGROUND
,
7404 IMAGEMAGICK_ROTATION
,
7409 /* Vector of image_keyword structures describing the format
7410 of valid user-defined image specifications. */
7412 static struct image_keyword imagemagick_format
[IMAGEMAGICK_LAST
] =
7414 {":type", IMAGE_SYMBOL_VALUE
, 1},
7415 {":data", IMAGE_STRING_VALUE
, 0},
7416 {":file", IMAGE_STRING_VALUE
, 0},
7417 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7418 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7419 {":relief", IMAGE_INTEGER_VALUE
, 0},
7420 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7421 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7422 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7423 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
7424 {":height", IMAGE_INTEGER_VALUE
, 0},
7425 {":width", IMAGE_INTEGER_VALUE
, 0},
7426 {":rotation", IMAGE_NUMBER_VALUE
, 0},
7427 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
7430 /* Structure describing the image type for any image handled via
7433 static struct image_type imagemagick_type
=
7436 imagemagick_image_p
,
7438 imagemagick_clear_image
,
7442 /* Free X resources of imagemagick image IMG which is used on frame F. */
7445 imagemagick_clear_image (struct frame
*f
,
7448 x_clear_image (f
, img
);
7451 /* Return non-zero if OBJECT is a valid IMAGEMAGICK image specification. Do
7452 this by calling parse_image_spec and supplying the keywords that
7453 identify the IMAGEMAGICK format. */
7456 imagemagick_image_p (Lisp_Object object
)
7458 struct image_keyword fmt
[IMAGEMAGICK_LAST
];
7459 memcpy (fmt
, imagemagick_format
, sizeof fmt
);
7461 if (!parse_image_spec (object
, fmt
, IMAGEMAGICK_LAST
, Qimagemagick
))
7464 /* Must specify either the :data or :file keyword. */
7465 return fmt
[IMAGEMAGICK_FILE
].count
+ fmt
[IMAGEMAGICK_DATA
].count
== 1;
7468 /* The GIF library also defines DrawRectangle, but its never used in Emacs.
7469 Therefore rename the function so it doesnt collide with ImageMagick. */
7470 #define DrawRectangle DrawRectangleGif
7471 #include <wand/MagickWand.h>
7473 /* ImageMagick 6.5.3 through 6.6.5 hid PixelGetMagickColor for some reason.
7474 Emacs seems to work fine with the hidden version, so unhide it. */
7475 #include <magick/version.h>
7476 #if 0x653 <= MagickLibVersion && MagickLibVersion <= 0x665
7477 extern WandExport
void PixelGetMagickColor (const PixelWand
*,
7478 MagickPixelPacket
*);
7481 /* Helper function for imagemagick_load, which does the actual loading
7482 given contents and size, apart from frame and image structures,
7483 passed from imagemagick_load. Uses librimagemagick to do most of
7484 the image processing.
7486 F is a pointer to the Emacs frame; IMG to the image structure to
7487 prepare; CONTENTS is the string containing the IMAGEMAGICK data to
7488 be parsed; SIZE is the number of bytes of data; and FILENAME is
7489 either the file name or the image data.
7491 Return non-zero if successful. */
7494 imagemagick_load_image (struct frame
*f
, struct image
*img
,
7495 unsigned char *contents
, unsigned int size
,
7501 MagickBooleanType status
;
7507 MagickWand
*image_wand
;
7508 MagickWand
*ping_wand
;
7509 PixelIterator
*iterator
;
7511 MagickPixelPacket pixel
;
7516 int desired_width
, desired_height
;
7518 int imagemagick_rendermethod
;
7520 ImageInfo
*image_info
;
7521 ExceptionInfo
*exception
;
7525 /* Handle image index for image types who can contain more than one image.
7526 Interface :index is same as for GIF. First we "ping" the image to see how
7527 many sub-images it contains. Pinging is faster than loading the image to
7528 find out things about it. */
7530 /* Initialize the imagemagick environment. */
7531 MagickWandGenesis ();
7532 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
7533 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
7534 ping_wand
= NewMagickWand ();
7535 MagickSetResolution (ping_wand
, 2, 2);
7536 if (filename
!= NULL
)
7538 status
= MagickPingImage (ping_wand
, filename
);
7542 status
= MagickPingImageBlob (ping_wand
, contents
, size
);
7545 if (ino
>= MagickGetNumberImages (ping_wand
))
7547 image_error ("Invalid image number `%s' in image `%s'",
7549 DestroyMagickWand (ping_wand
);
7553 if (MagickGetNumberImages(ping_wand
) > 1)
7556 Fcons (make_number (MagickGetNumberImages (ping_wand
)),
7559 DestroyMagickWand (ping_wand
);
7561 /* Now we know how many images are inside the file. If it's not a
7562 bundle, the number is one. */
7564 if (filename
!= NULL
)
7566 image_info
= CloneImageInfo ((ImageInfo
*) NULL
);
7567 (void) strcpy (image_info
->filename
, filename
);
7568 image_info
->number_scenes
= 1;
7569 image_info
->scene
= ino
;
7570 exception
= AcquireExceptionInfo ();
7572 im_image
= ReadImage (image_info
, exception
);
7573 DestroyExceptionInfo (exception
);
7575 if (im_image
== NULL
)
7576 goto imagemagick_no_wand
;
7577 image_wand
= NewMagickWandFromImage (im_image
);
7578 DestroyImage(im_image
);
7582 image_wand
= NewMagickWand ();
7583 if (MagickReadImageBlob (image_wand
, contents
, size
) == MagickFalse
)
7584 goto imagemagick_error
;
7587 /* If width and/or height is set in the display spec assume we want
7588 to scale to those values. If either h or w is unspecified, the
7589 unspecified should be calculated from the specified to preserve
7592 value
= image_spec_value (img
->spec
, QCwidth
, NULL
);
7593 desired_width
= (INTEGERP (value
) ? XFASTINT (value
) : -1);
7594 value
= image_spec_value (img
->spec
, QCheight
, NULL
);
7595 desired_height
= (INTEGERP (value
) ? XFASTINT (value
) : -1);
7597 height
= MagickGetImageHeight (image_wand
);
7598 width
= MagickGetImageWidth (image_wand
);
7600 if (desired_width
!= -1 && desired_height
== -1)
7601 /* w known, calculate h. */
7602 desired_height
= (double) desired_width
/ width
* height
;
7603 if (desired_width
== -1 && desired_height
!= -1)
7604 /* h known, calculate w. */
7605 desired_width
= (double) desired_height
/ height
* width
;
7606 if (desired_width
!= -1 && desired_height
!= -1)
7608 status
= MagickScaleImage (image_wand
, desired_width
, desired_height
);
7609 if (status
== MagickFalse
)
7611 image_error ("Imagemagick scale failed", Qnil
, Qnil
);
7612 goto imagemagick_error
;
7616 /* crop behaves similar to image slicing in Emacs but is more memory
7618 crop
= image_spec_value (img
->spec
, QCcrop
, NULL
);
7620 if (CONSP (crop
) && INTEGERP (XCAR (crop
)))
7622 /* After some testing, it seems MagickCropImage is the fastest crop
7623 function in ImageMagick. This crop function seems to do less copying
7624 than the alternatives, but it still reads the entire image into memory
7625 before croping, which is aparently difficult to avoid when using
7628 w
= XFASTINT (XCAR (crop
));
7630 if (CONSP (crop
) && INTEGERP (XCAR (crop
)))
7632 h
= XFASTINT (XCAR (crop
));
7634 if (CONSP (crop
) && INTEGERP (XCAR (crop
)))
7636 x
= XFASTINT (XCAR (crop
));
7638 if (CONSP (crop
) && INTEGERP (XCAR (crop
)))
7640 y
= XFASTINT (XCAR (crop
));
7641 MagickCropImage (image_wand
, w
, h
, x
, y
);
7647 /* Furthermore :rotation. we need background color and angle for
7650 TODO background handling for rotation specified_bg =
7651 image_spec_value (img->spec, QCbackground, NULL); if (!STRINGP
7653 value
= image_spec_value (img
->spec
, QCrotation
, NULL
);
7656 PixelWand
* background
= NewPixelWand ();
7657 PixelSetColor (background
, "#ffffff");/*TODO remove hardcode*/
7659 rotation
= extract_float (value
);
7661 status
= MagickRotateImage (image_wand
, background
, rotation
);
7662 DestroyPixelWand (background
);
7663 if (status
== MagickFalse
)
7665 image_error ("Imagemagick image rotate failed", Qnil
, Qnil
);
7666 goto imagemagick_error
;
7670 /* Finally we are done manipulating the image. Figure out the
7671 resulting width/height and transfer ownerwship to Emacs. */
7672 height
= MagickGetImageHeight (image_wand
);
7673 width
= MagickGetImageWidth (image_wand
);
7675 if (! check_image_size (f
, width
, height
))
7677 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7678 goto imagemagick_error
;
7681 /* We can now get a valid pixel buffer from the imagemagick file, if all
7684 init_color_table ();
7685 imagemagick_rendermethod
= (INTEGERP (Vimagemagick_render_type
)
7686 ? XFASTINT (Vimagemagick_render_type
) : 0);
7687 if (imagemagick_rendermethod
== 0)
7689 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7690 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
7691 &ximg
, &img
->pixmap
))
7693 #ifdef COLOR_TABLE_SUPPORT
7694 free_color_table ();
7696 image_error("Imagemagick X bitmap allocation failure", Qnil
, Qnil
);
7697 goto imagemagick_error
;
7700 /* Copy imagegmagick image to x with primitive yet robust pixel
7701 pusher loop. This has been tested a lot with many different
7704 /* Copy pixels from the imagemagick image structure to the x image map. */
7705 iterator
= NewPixelIterator (image_wand
);
7706 if (iterator
== (PixelIterator
*) NULL
)
7708 #ifdef COLOR_TABLE_SUPPORT
7709 free_color_table ();
7711 x_destroy_x_image (ximg
);
7712 image_error ("Imagemagick pixel iterator creation failed",
7714 goto imagemagick_error
;
7717 for (y
= 0; y
< (long) MagickGetImageHeight (image_wand
); y
++)
7719 pixels
= PixelGetNextIteratorRow (iterator
, &width
);
7720 if (pixels
== (PixelWand
**) NULL
)
7722 for (x
= 0; x
< (long) width
; x
++)
7724 PixelGetMagickColor (pixels
[x
], &pixel
);
7725 XPutPixel (ximg
, x
, y
,
7726 lookup_rgb_color (f
,
7732 DestroyPixelIterator (iterator
);
7735 if (imagemagick_rendermethod
== 1)
7737 /* Magicexportimage is normaly faster than pixelpushing. This
7738 method is also well tested. Some aspects of this method are
7739 ad-hoc and needs to be more researched. */
7740 int imagedepth
= 24;/*MagickGetImageDepth(image_wand);*/
7741 const char *exportdepth
= imagedepth
<= 8 ? "I" : "BGRP";/*"RGBP";*/
7742 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7743 if (!x_create_x_image_and_pixmap (f
, width
, height
, imagedepth
,
7744 &ximg
, &img
->pixmap
))
7746 #ifdef COLOR_TABLE_SUPPORT
7747 free_color_table ();
7749 image_error("Imagemagick X bitmap allocation failure", Qnil
, Qnil
);
7750 goto imagemagick_error
;
7754 /* Oddly, the below code doesnt seem to work:*/
7755 /* switch(ximg->bitmap_unit){ */
7757 /* pixelwidth=CharPixel; */
7760 /* pixelwidth=ShortPixel; */
7763 /* pixelwidth=LongPixel; */
7767 Here im just guessing the format of the bitmap.
7768 happens to work fine for:
7771 seems about 3 times as fast as pixel pushing(not carefully measured)
7773 pixelwidth
= CharPixel
;/*??? TODO figure out*/
7774 #ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
7775 MagickExportImagePixels (image_wand
,
7780 /*&(img->pixmap));*/
7783 image_error ("You dont have MagickExportImagePixels, upgrade ImageMagick!",
7789 #ifdef COLOR_TABLE_SUPPORT
7790 /* Remember colors allocated for this image. */
7791 img
->colors
= colors_in_color_table (&img
->ncolors
);
7792 free_color_table ();
7793 #endif /* COLOR_TABLE_SUPPORT */
7797 img
->height
= height
;
7799 /* Put the image into the pixmap, then free the X image and its
7801 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7802 x_destroy_x_image (ximg
);
7805 /* Final cleanup. image_wand should be the only resource left. */
7806 DestroyMagickWand (image_wand
);
7807 /* `MagickWandTerminus' terminates the imagemagick environment. */
7808 MagickWandTerminus ();
7813 DestroyMagickWand (image_wand
);
7814 imagemagick_no_wand
:
7815 MagickWandTerminus ();
7816 /* TODO more cleanup. */
7817 image_error ("Error parsing IMAGEMAGICK image `%s'", img
->spec
, Qnil
);
7822 /* Load IMAGEMAGICK image IMG for use on frame F. Value is non-zero if
7823 successful. this function will go into the imagemagick_type structure, and
7824 the prototype thus needs to be compatible with that structure. */
7827 imagemagick_load (struct frame
*f
, struct image
*img
)
7830 Lisp_Object file_name
;
7832 /* If IMG->spec specifies a file name, create a non-file spec from it. */
7833 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
7834 if (STRINGP (file_name
))
7838 file
= x_find_image_file (file_name
);
7839 if (!STRINGP (file
))
7841 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
7844 success_p
= imagemagick_load_image (f
, img
, 0, 0, SSDATA (file
));
7846 /* Else its not a file, its a lisp object. Load the image from a
7847 lisp object rather than a file. */
7852 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7853 if (!STRINGP (data
))
7855 image_error ("Invalid image data `%s'", data
, Qnil
);
7858 success_p
= imagemagick_load_image (f
, img
, SDATA (data
),
7859 SBYTES (data
), NULL
);
7865 DEFUN ("imagemagick-types", Fimagemagick_types
, Simagemagick_types
, 0, 0, 0,
7866 doc
: /* Return a list of image types supported by ImageMagick.
7867 Each entry in this list is a symbol named after an ImageMagick format
7868 tag. See the ImageMagick manual for a list of ImageMagick formats and
7869 their descriptions (http://www.imagemagick.org/script/formats.php).
7871 Note that ImageMagick recognizes many file-types that Emacs does not
7872 recognize as images, such as C. See `imagemagick-types-inhibit'. */)
7875 Lisp_Object typelist
= Qnil
;
7878 char **imtypes
= GetMagickList ("*", &numf
, &ex
);
7880 Lisp_Object Qimagemagicktype
;
7881 for (i
= 0; i
< numf
; i
++)
7883 Qimagemagicktype
= intern (imtypes
[i
]);
7884 typelist
= Fcons (Qimagemagicktype
, typelist
);
7889 #endif /* defined (HAVE_IMAGEMAGICK) */
7893 /***********************************************************************
7895 ***********************************************************************/
7897 #if defined (HAVE_RSVG)
7899 /* Function prototypes. */
7901 static int svg_image_p (Lisp_Object object
);
7902 static int svg_load (struct frame
*f
, struct image
*img
);
7904 static int svg_load_image (struct frame
*, struct image
*,
7905 unsigned char *, ptrdiff_t);
7907 /* The symbol `svg' identifying images of this type. */
7909 static Lisp_Object Qsvg
;
7911 /* Indices of image specification fields in svg_format, below. */
7913 enum svg_keyword_index
7928 /* Vector of image_keyword structures describing the format
7929 of valid user-defined image specifications. */
7931 static const struct image_keyword svg_format
[SVG_LAST
] =
7933 {":type", IMAGE_SYMBOL_VALUE
, 1},
7934 {":data", IMAGE_STRING_VALUE
, 0},
7935 {":file", IMAGE_STRING_VALUE
, 0},
7936 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7937 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7938 {":relief", IMAGE_INTEGER_VALUE
, 0},
7939 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7940 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7941 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7942 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7945 /* Structure describing the image type `svg'. Its the same type of
7946 structure defined for all image formats, handled by emacs image
7947 functions. See struct image_type in dispextern.h. */
7949 static struct image_type svg_type
=
7951 /* An identifier showing that this is an image structure for the SVG format. */
7953 /* Handle to a function that can be used to identify a SVG file. */
7955 /* Handle to function used to load a SVG file. */
7957 /* Handle to function to free sresources for SVG. */
7959 /* An internal field to link to the next image type in a list of
7960 image types, will be filled in when registering the format. */
7965 /* Return non-zero if OBJECT is a valid SVG image specification. Do
7966 this by calling parse_image_spec and supplying the keywords that
7967 identify the SVG format. */
7970 svg_image_p (Lisp_Object object
)
7972 struct image_keyword fmt
[SVG_LAST
];
7973 memcpy (fmt
, svg_format
, sizeof fmt
);
7975 if (!parse_image_spec (object
, fmt
, SVG_LAST
, Qsvg
))
7978 /* Must specify either the :data or :file keyword. */
7979 return fmt
[SVG_FILE
].count
+ fmt
[SVG_DATA
].count
== 1;
7982 #include <librsvg/rsvg.h>
7986 /* SVG library functions. */
7987 DEF_IMGLIB_FN (RsvgHandle
*, rsvg_handle_new
);
7988 DEF_IMGLIB_FN (void, rsvg_handle_get_dimensions
);
7989 DEF_IMGLIB_FN (gboolean
, rsvg_handle_write
);
7990 DEF_IMGLIB_FN (gboolean
, rsvg_handle_close
);
7991 DEF_IMGLIB_FN (GdkPixbuf
*, rsvg_handle_get_pixbuf
);
7993 DEF_IMGLIB_FN (int, gdk_pixbuf_get_width
);
7994 DEF_IMGLIB_FN (int, gdk_pixbuf_get_height
);
7995 DEF_IMGLIB_FN (guchar
*, gdk_pixbuf_get_pixels
);
7996 DEF_IMGLIB_FN (int, gdk_pixbuf_get_rowstride
);
7997 DEF_IMGLIB_FN (GdkColorspace
, gdk_pixbuf_get_colorspace
);
7998 DEF_IMGLIB_FN (int, gdk_pixbuf_get_n_channels
);
7999 DEF_IMGLIB_FN (gboolean
, gdk_pixbuf_get_has_alpha
);
8000 DEF_IMGLIB_FN (int, gdk_pixbuf_get_bits_per_sample
);
8002 DEF_IMGLIB_FN (void, g_type_init
);
8003 DEF_IMGLIB_FN (void, g_object_unref
);
8004 DEF_IMGLIB_FN (void, g_error_free
);
8006 Lisp_Object Qgdk_pixbuf
, Qglib
, Qgobject
;
8009 init_svg_functions (Lisp_Object libraries
)
8011 HMODULE library
, gdklib
, glib
, gobject
;
8013 if (!(glib
= w32_delayed_load (libraries
, Qglib
))
8014 || !(gobject
= w32_delayed_load (libraries
, Qgobject
))
8015 || !(gdklib
= w32_delayed_load (libraries
, Qgdk_pixbuf
))
8016 || !(library
= w32_delayed_load (libraries
, Qsvg
)))
8019 LOAD_IMGLIB_FN (library
, rsvg_handle_new
);
8020 LOAD_IMGLIB_FN (library
, rsvg_handle_get_dimensions
);
8021 LOAD_IMGLIB_FN (library
, rsvg_handle_write
);
8022 LOAD_IMGLIB_FN (library
, rsvg_handle_close
);
8023 LOAD_IMGLIB_FN (library
, rsvg_handle_get_pixbuf
);
8025 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_width
);
8026 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_height
);
8027 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_pixels
);
8028 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_rowstride
);
8029 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_colorspace
);
8030 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_n_channels
);
8031 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_has_alpha
);
8032 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_bits_per_sample
);
8034 LOAD_IMGLIB_FN (gobject
, g_type_init
);
8035 LOAD_IMGLIB_FN (gobject
, g_object_unref
);
8036 LOAD_IMGLIB_FN (glib
, g_error_free
);
8042 /* The following aliases for library functions allow dynamic loading
8043 to be used on some platforms. */
8044 #define fn_rsvg_handle_new rsvg_handle_new
8045 #define fn_rsvg_handle_get_dimensions rsvg_handle_get_dimensions
8046 #define fn_rsvg_handle_write rsvg_handle_write
8047 #define fn_rsvg_handle_close rsvg_handle_close
8048 #define fn_rsvg_handle_get_pixbuf rsvg_handle_get_pixbuf
8050 #define fn_gdk_pixbuf_get_width gdk_pixbuf_get_width
8051 #define fn_gdk_pixbuf_get_height gdk_pixbuf_get_height
8052 #define fn_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels
8053 #define fn_gdk_pixbuf_get_rowstride gdk_pixbuf_get_rowstride
8054 #define fn_gdk_pixbuf_get_colorspace gdk_pixbuf_get_colorspace
8055 #define fn_gdk_pixbuf_get_n_channels gdk_pixbuf_get_n_channels
8056 #define fn_gdk_pixbuf_get_has_alpha gdk_pixbuf_get_has_alpha
8057 #define fn_gdk_pixbuf_get_bits_per_sample gdk_pixbuf_get_bits_per_sample
8059 #define fn_g_type_init g_type_init
8060 #define fn_g_object_unref g_object_unref
8061 #define fn_g_error_free g_error_free
8062 #endif /* !HAVE_NTGUI */
8064 /* Load SVG image IMG for use on frame F. Value is non-zero if
8065 successful. this function will go into the svg_type structure, and
8066 the prototype thus needs to be compatible with that structure. */
8069 svg_load (struct frame
*f
, struct image
*img
)
8072 Lisp_Object file_name
;
8074 /* If IMG->spec specifies a file name, create a non-file spec from it. */
8075 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
8076 if (STRINGP (file_name
))
8079 unsigned char *contents
;
8082 file
= x_find_image_file (file_name
);
8083 if (!STRINGP (file
))
8085 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
8089 /* Read the entire file into memory. */
8090 contents
= slurp_file (SSDATA (file
), &size
);
8091 if (contents
== NULL
)
8093 image_error ("Error loading SVG image `%s'", img
->spec
, Qnil
);
8096 /* If the file was slurped into memory properly, parse it. */
8097 success_p
= svg_load_image (f
, img
, contents
, size
);
8100 /* Else its not a file, its a lisp object. Load the image from a
8101 lisp object rather than a file. */
8106 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8107 if (!STRINGP (data
))
8109 image_error ("Invalid image data `%s'", data
, Qnil
);
8112 success_p
= svg_load_image (f
, img
, SDATA (data
), SBYTES (data
));
8118 /* svg_load_image is a helper function for svg_load, which does the
8119 actual loading given contents and size, apart from frame and image
8120 structures, passed from svg_load.
8122 Uses librsvg to do most of the image processing.
8124 Returns non-zero when successful. */
8126 svg_load_image (struct frame
*f
, /* Pointer to emacs frame structure. */
8127 struct image
*img
, /* Pointer to emacs image structure. */
8128 unsigned char *contents
, /* String containing the SVG XML data to be parsed. */
8129 ptrdiff_t size
) /* Size of data in bytes. */
8131 RsvgHandle
*rsvg_handle
;
8132 RsvgDimensionData dimension_data
;
8137 const guint8
*pixels
;
8140 Lisp_Object specified_bg
;
8145 /* g_type_init is a glib function that must be called prior to using
8146 gnome type library functions. */
8148 /* Make a handle to a new rsvg object. */
8149 rsvg_handle
= fn_rsvg_handle_new ();
8151 /* Parse the contents argument and fill in the rsvg_handle. */
8152 fn_rsvg_handle_write (rsvg_handle
, contents
, size
, &err
);
8153 if (err
) goto rsvg_error
;
8155 /* The parsing is complete, rsvg_handle is ready to used, close it
8156 for further writes. */
8157 fn_rsvg_handle_close (rsvg_handle
, &err
);
8158 if (err
) goto rsvg_error
;
8160 fn_rsvg_handle_get_dimensions (rsvg_handle
, &dimension_data
);
8161 if (! check_image_size (f
, dimension_data
.width
, dimension_data
.height
))
8163 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
8167 /* We can now get a valid pixel buffer from the svg file, if all
8169 pixbuf
= fn_rsvg_handle_get_pixbuf (rsvg_handle
);
8170 if (!pixbuf
) goto rsvg_error
;
8171 fn_g_object_unref (rsvg_handle
);
8173 /* Extract some meta data from the svg handle. */
8174 width
= fn_gdk_pixbuf_get_width (pixbuf
);
8175 height
= fn_gdk_pixbuf_get_height (pixbuf
);
8176 pixels
= fn_gdk_pixbuf_get_pixels (pixbuf
);
8177 rowstride
= fn_gdk_pixbuf_get_rowstride (pixbuf
);
8179 /* Validate the svg meta data. */
8180 eassert (fn_gdk_pixbuf_get_colorspace (pixbuf
) == GDK_COLORSPACE_RGB
);
8181 eassert (fn_gdk_pixbuf_get_n_channels (pixbuf
) == 4);
8182 eassert (fn_gdk_pixbuf_get_has_alpha (pixbuf
));
8183 eassert (fn_gdk_pixbuf_get_bits_per_sample (pixbuf
) == 8);
8185 /* Try to create a x pixmap to hold the svg pixmap. */
8186 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8188 fn_g_object_unref (pixbuf
);
8192 init_color_table ();
8194 /* Handle alpha channel by combining the image with a background
8196 specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
8197 if (!STRINGP (specified_bg
)
8198 || !x_defined_color (f
, SSDATA (specified_bg
), &background
, 0))
8201 background
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
8202 x_query_color (f
, &background
);
8204 ns_query_color (FRAME_BACKGROUND_COLOR (f
), &background
, 1);
8208 /* SVG pixmaps specify transparency in the last byte, so right
8209 shift 8 bits to get rid of it, since emacs doesn't support
8211 background
.red
>>= 8;
8212 background
.green
>>= 8;
8213 background
.blue
>>= 8;
8215 /* This loop handles opacity values, since Emacs assumes
8216 non-transparent images. Each pixel must be "flattened" by
8217 calculating the resulting color, given the transparency of the
8218 pixel, and the image background color. */
8219 for (y
= 0; y
< height
; ++y
)
8221 for (x
= 0; x
< width
; ++x
)
8231 opacity
= *pixels
++;
8233 red
= ((red
* opacity
)
8234 + (background
.red
* ((1 << 8) - opacity
)));
8235 green
= ((green
* opacity
)
8236 + (background
.green
* ((1 << 8) - opacity
)));
8237 blue
= ((blue
* opacity
)
8238 + (background
.blue
* ((1 << 8) - opacity
)));
8240 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, red
, green
, blue
));
8243 pixels
+= rowstride
- 4 * width
;
8246 #ifdef COLOR_TABLE_SUPPORT
8247 /* Remember colors allocated for this image. */
8248 img
->colors
= colors_in_color_table (&img
->ncolors
);
8249 free_color_table ();
8250 #endif /* COLOR_TABLE_SUPPORT */
8252 fn_g_object_unref (pixbuf
);
8255 img
->height
= height
;
8257 /* Maybe fill in the background field while we have ximg handy.
8258 Casting avoids a GCC warning. */
8259 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
8261 /* Put the image into the pixmap, then free the X image and its
8263 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8264 x_destroy_x_image (ximg
);
8269 fn_g_object_unref (rsvg_handle
);
8270 /* FIXME: Use error->message so the user knows what is the actual
8271 problem with the image. */
8272 image_error ("Error parsing SVG image `%s'", img
->spec
, Qnil
);
8273 fn_g_error_free (err
);
8277 #endif /* defined (HAVE_RSVG) */
8282 /***********************************************************************
8284 ***********************************************************************/
8286 #ifdef HAVE_X_WINDOWS
8287 #define HAVE_GHOSTSCRIPT 1
8288 #endif /* HAVE_X_WINDOWS */
8290 #ifdef HAVE_GHOSTSCRIPT
8292 static int gs_image_p (Lisp_Object object
);
8293 static int gs_load (struct frame
*f
, struct image
*img
);
8294 static void gs_clear_image (struct frame
*f
, struct image
*img
);
8296 /* Keyword symbols. */
8298 static Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
8300 /* Indices of image specification fields in gs_format, below. */
8302 enum gs_keyword_index
8320 /* Vector of image_keyword structures describing the format
8321 of valid user-defined image specifications. */
8323 static const struct image_keyword gs_format
[GS_LAST
] =
8325 {":type", IMAGE_SYMBOL_VALUE
, 1},
8326 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8327 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8328 {":file", IMAGE_STRING_VALUE
, 1},
8329 {":loader", IMAGE_FUNCTION_VALUE
, 0},
8330 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
8331 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8332 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8333 {":relief", IMAGE_INTEGER_VALUE
, 0},
8334 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8335 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8336 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8337 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8340 /* Structure describing the image type `ghostscript'. */
8342 static struct image_type gs_type
=
8352 /* Free X resources of Ghostscript image IMG which is used on frame F. */
8355 gs_clear_image (struct frame
*f
, struct image
*img
)
8357 x_clear_image (f
, img
);
8361 /* Return non-zero if OBJECT is a valid Ghostscript image
8365 gs_image_p (Lisp_Object object
)
8367 struct image_keyword fmt
[GS_LAST
];
8371 memcpy (fmt
, gs_format
, sizeof fmt
);
8373 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
8376 /* Bounding box must be a list or vector containing 4 integers. */
8377 tem
= fmt
[GS_BOUNDING_BOX
].value
;
8380 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
8381 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
8386 else if (VECTORP (tem
))
8388 if (ASIZE (tem
) != 4)
8390 for (i
= 0; i
< 4; ++i
)
8391 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
8401 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
8405 gs_load (struct frame
*f
, struct image
*img
)
8408 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
8410 double in_width
, in_height
;
8411 Lisp_Object pixel_colors
= Qnil
;
8413 /* Compute pixel size of pixmap needed from the given size in the
8414 image specification. Sizes in the specification are in pt. 1 pt
8415 = 1/72 in, xdpi and ydpi are stored in the frame's X display
8417 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
8418 in_width
= INTEGERP (pt_width
) ? XFASTINT (pt_width
) / 72.0 : 0;
8419 img
->width
= in_width
* FRAME_X_DISPLAY_INFO (f
)->resx
;
8420 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
8421 in_height
= INTEGERP (pt_height
) ? XFASTINT (pt_height
) / 72.0 : 0;
8422 img
->height
= in_height
* FRAME_X_DISPLAY_INFO (f
)->resy
;
8424 if (!check_image_size (f
, img
->width
, img
->height
))
8426 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
8430 /* Create the pixmap. */
8431 xassert (img
->pixmap
== NO_PIXMAP
);
8433 /* Only W32 version did BLOCK_INPUT here. ++kfs */
8435 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8436 img
->width
, img
->height
,
8437 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
8442 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
8446 /* Call the loader to fill the pixmap. It returns a process object
8447 if successful. We do not record_unwind_protect here because
8448 other places in redisplay like calling window scroll functions
8449 don't either. Let the Lisp loader use `unwind-protect' instead. */
8450 sprintf (buffer
, "%lu %lu",
8451 (unsigned long) FRAME_X_WINDOW (f
),
8452 (unsigned long) img
->pixmap
);
8453 window_and_pixmap_id
= build_string (buffer
);
8455 sprintf (buffer
, "%lu %lu",
8456 FRAME_FOREGROUND_PIXEL (f
),
8457 FRAME_BACKGROUND_PIXEL (f
));
8458 pixel_colors
= build_string (buffer
);
8460 XSETFRAME (frame
, f
);
8461 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
8463 loader
= intern ("gs-load-image");
8465 img
->lisp_data
= call6 (loader
, frame
, img
->spec
,
8466 make_number (img
->width
),
8467 make_number (img
->height
),
8468 window_and_pixmap_id
,
8470 return PROCESSP (img
->lisp_data
);
8474 /* Kill the Ghostscript process that was started to fill PIXMAP on
8475 frame F. Called from XTread_socket when receiving an event
8476 telling Emacs that Ghostscript has finished drawing. */
8479 x_kill_gs_process (Pixmap pixmap
, struct frame
*f
)
8481 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
8485 /* Find the image containing PIXMAP. */
8486 for (i
= 0; i
< c
->used
; ++i
)
8487 if (c
->images
[i
]->pixmap
== pixmap
)
8490 /* Should someone in between have cleared the image cache, for
8491 instance, give up. */
8495 /* Kill the GS process. We should have found PIXMAP in the image
8496 cache and its image should contain a process object. */
8498 xassert (PROCESSP (img
->lisp_data
));
8499 Fkill_process (img
->lisp_data
, Qnil
);
8500 img
->lisp_data
= Qnil
;
8502 #if defined (HAVE_X_WINDOWS)
8504 /* On displays with a mutable colormap, figure out the colors
8505 allocated for the image by looking at the pixels of an XImage for
8507 class = FRAME_X_VISUAL (f
)->class;
8508 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
8514 /* Try to get an XImage for img->pixmep. */
8515 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
8516 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
8521 /* Initialize the color table. */
8522 init_color_table ();
8524 /* For each pixel of the image, look its color up in the
8525 color table. After having done so, the color table will
8526 contain an entry for each color used by the image. */
8527 for (y
= 0; y
< img
->height
; ++y
)
8528 for (x
= 0; x
< img
->width
; ++x
)
8530 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
8531 lookup_pixel_color (f
, pixel
);
8534 /* Record colors in the image. Free color table and XImage. */
8535 #ifdef COLOR_TABLE_SUPPORT
8536 img
->colors
= colors_in_color_table (&img
->ncolors
);
8537 free_color_table ();
8539 XDestroyImage (ximg
);
8541 #if 0 /* This doesn't seem to be the case. If we free the colors
8542 here, we get a BadAccess later in x_clear_image when
8543 freeing the colors. */
8544 /* We have allocated colors once, but Ghostscript has also
8545 allocated colors on behalf of us. So, to get the
8546 reference counts right, free them once. */
8548 x_free_colors (f
, img
->colors
, img
->ncolors
);
8552 image_error ("Cannot get X image of `%s'; colors will not be freed",
8557 #endif /* HAVE_X_WINDOWS */
8559 /* Now that we have the pixmap, compute mask and transform the
8560 image if requested. */
8562 postprocess_image (f
, img
);
8566 #endif /* HAVE_GHOSTSCRIPT */
8569 /***********************************************************************
8571 ***********************************************************************/
8575 DEFUN ("imagep", Fimagep
, Simagep
, 1, 1, 0,
8576 doc
: /* Value is non-nil if SPEC is a valid image specification. */)
8579 return valid_image_p (spec
) ? Qt
: Qnil
;
8583 DEFUN ("lookup-image", Flookup_image
, Slookup_image
, 1, 1, 0, "")
8588 if (valid_image_p (spec
))
8589 id
= lookup_image (SELECTED_FRAME (), spec
);
8592 return make_number (id
);
8595 #endif /* GLYPH_DEBUG != 0 */
8598 /***********************************************************************
8600 ***********************************************************************/
8603 /* Image types that rely on external libraries are loaded dynamically
8604 if the library is available. */
8605 #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8606 define_image_type (image_type, init_lib_fn (libraries))
8608 #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8609 define_image_type (image_type, 1)
8610 #endif /* HAVE_NTGUI */
8612 DEFUN ("init-image-library", Finit_image_library
, Sinit_image_library
, 2, 2, 0,
8613 doc
: /* Initialize image library implementing image type TYPE.
8614 Return non-nil if TYPE is a supported image type.
8616 Image types pbm and xbm are prebuilt; other types are loaded here.
8617 Libraries to load are specified in alist LIBRARIES (usually, the value
8618 of `dynamic-library-alist', which see). */)
8619 (Lisp_Object type
, Lisp_Object libraries
)
8622 /* Don't try to reload the library. */
8623 Lisp_Object tested
= Fassq (type
, Vlibrary_cache
);
8625 return XCDR (tested
);
8628 /* Types pbm and xbm are built-in and always available. */
8629 if (EQ (type
, Qpbm
) || EQ (type
, Qxbm
))
8632 #if defined (HAVE_XPM) || defined (HAVE_NS)
8633 if (EQ (type
, Qxpm
))
8634 return CHECK_LIB_AVAILABLE (&xpm_type
, init_xpm_functions
, libraries
);
8637 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8638 if (EQ (type
, Qjpeg
))
8639 return CHECK_LIB_AVAILABLE (&jpeg_type
, init_jpeg_functions
, libraries
);
8642 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8643 if (EQ (type
, Qtiff
))
8644 return CHECK_LIB_AVAILABLE (&tiff_type
, init_tiff_functions
, libraries
);
8647 #if defined (HAVE_GIF) || defined (HAVE_NS)
8648 if (EQ (type
, Qgif
))
8649 return CHECK_LIB_AVAILABLE (&gif_type
, init_gif_functions
, libraries
);
8652 #if defined (HAVE_PNG) || defined (HAVE_NS)
8653 if (EQ (type
, Qpng
))
8654 return CHECK_LIB_AVAILABLE (&png_type
, init_png_functions
, libraries
);
8657 #if defined (HAVE_RSVG)
8658 if (EQ (type
, Qsvg
))
8659 return CHECK_LIB_AVAILABLE (&svg_type
, init_svg_functions
, libraries
);
8662 #if defined (HAVE_IMAGEMAGICK)
8663 if (EQ (type
, Qimagemagick
))
8664 return CHECK_LIB_AVAILABLE (&imagemagick_type
, init_imagemagick_functions
,
8668 #ifdef HAVE_GHOSTSCRIPT
8669 if (EQ (type
, Qpostscript
))
8670 return CHECK_LIB_AVAILABLE (&gs_type
, init_gs_functions
, libraries
);
8673 /* If the type is not recognized, avoid testing it ever again. */
8674 CACHE_IMAGE_TYPE (type
, Qnil
);
8679 syms_of_image (void)
8681 /* Initialize this only once, since that's what we do with Vimage_types
8682 and they are supposed to be in sync. Initializing here gives correct
8683 operation on GNU/Linux of calling dump-emacs after loading some images. */
8686 /* Must be defined now becase we're going to update it below, while
8687 defining the supported image types. */
8688 DEFVAR_LISP ("image-types", Vimage_types
,
8689 doc
: /* List of potentially supported image types.
8690 Each element of the list is a symbol for an image type, like 'jpeg or 'png.
8691 To check whether it is really supported, use `image-type-available-p'. */);
8692 Vimage_types
= Qnil
;
8694 DEFVAR_LISP ("max-image-size", Vmax_image_size
,
8695 doc
: /* Maximum size of images.
8696 Emacs will not load an image into memory if its pixel width or
8697 pixel height exceeds this limit.
8699 If the value is an integer, it directly specifies the maximum
8700 image height and width, measured in pixels. If it is a floating
8701 point number, it specifies the maximum image height and width
8702 as a ratio to the frame height and width. If the value is
8703 non-numeric, there is no explicit limit on the size of images. */);
8704 Vmax_image_size
= make_float (MAX_IMAGE_SIZE
);
8706 DEFSYM (Qpbm
, "pbm");
8707 ADD_IMAGE_TYPE (Qpbm
);
8709 DEFSYM (Qxbm
, "xbm");
8710 ADD_IMAGE_TYPE (Qxbm
);
8712 define_image_type (&xbm_type
, 1);
8713 define_image_type (&pbm_type
, 1);
8715 DEFSYM (Qcount
, "count");
8716 DEFSYM (Qextension_data
, "extension-data");
8717 DEFSYM (Qdelay
, "delay");
8719 DEFSYM (QCascent
, ":ascent");
8720 DEFSYM (QCmargin
, ":margin");
8721 DEFSYM (QCrelief
, ":relief");
8722 DEFSYM (QCconversion
, ":conversion");
8723 DEFSYM (QCcolor_symbols
, ":color-symbols");
8724 DEFSYM (QCheuristic_mask
, ":heuristic-mask");
8725 DEFSYM (QCindex
, ":index");
8726 DEFSYM (QCgeometry
, ":geometry");
8727 DEFSYM (QCcrop
, ":crop");
8728 DEFSYM (QCrotation
, ":rotation");
8729 DEFSYM (QCmatrix
, ":matrix");
8730 DEFSYM (QCcolor_adjustment
, ":color-adjustment");
8731 DEFSYM (QCmask
, ":mask");
8733 DEFSYM (Qlaplace
, "laplace");
8734 DEFSYM (Qemboss
, "emboss");
8735 DEFSYM (Qedge_detection
, "edge-detection");
8736 DEFSYM (Qheuristic
, "heuristic");
8738 DEFSYM (Qpostscript
, "postscript");
8739 #ifdef HAVE_GHOSTSCRIPT
8740 ADD_IMAGE_TYPE (Qpostscript
);
8741 DEFSYM (QCloader
, ":loader");
8742 DEFSYM (QCbounding_box
, ":bounding-box");
8743 DEFSYM (QCpt_width
, ":pt-width");
8744 DEFSYM (QCpt_height
, ":pt-height");
8745 #endif /* HAVE_GHOSTSCRIPT */
8748 DEFSYM (Qlibpng_version
, "libpng-version");
8749 Fset (Qlibpng_version
,
8751 make_number (PNG_LIBPNG_VER
)
8758 #if defined (HAVE_XPM) || defined (HAVE_NS)
8759 DEFSYM (Qxpm
, "xpm");
8760 ADD_IMAGE_TYPE (Qxpm
);
8763 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8764 DEFSYM (Qjpeg
, "jpeg");
8765 ADD_IMAGE_TYPE (Qjpeg
);
8768 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8769 DEFSYM (Qtiff
, "tiff");
8770 ADD_IMAGE_TYPE (Qtiff
);
8773 #if defined (HAVE_GIF) || defined (HAVE_NS)
8774 DEFSYM (Qgif
, "gif");
8775 ADD_IMAGE_TYPE (Qgif
);
8778 #if defined (HAVE_PNG) || defined (HAVE_NS)
8779 DEFSYM (Qpng
, "png");
8780 ADD_IMAGE_TYPE (Qpng
);
8783 #if defined (HAVE_IMAGEMAGICK)
8784 DEFSYM (Qimagemagick
, "imagemagick");
8785 ADD_IMAGE_TYPE (Qimagemagick
);
8788 #if defined (HAVE_RSVG)
8789 DEFSYM (Qsvg
, "svg");
8790 ADD_IMAGE_TYPE (Qsvg
);
8792 /* Other libraries used directly by svg code. */
8793 DEFSYM (Qgdk_pixbuf
, "gdk-pixbuf");
8794 DEFSYM (Qglib
, "glib");
8795 DEFSYM (Qgobject
, "gobject");
8796 #endif /* HAVE_NTGUI */
8797 #endif /* HAVE_RSVG */
8799 defsubr (&Sinit_image_library
);
8800 #ifdef HAVE_IMAGEMAGICK
8801 defsubr (&Simagemagick_types
);
8803 defsubr (&Sclear_image_cache
);
8804 defsubr (&Simage_flush
);
8805 defsubr (&Simage_size
);
8806 defsubr (&Simage_mask_p
);
8807 defsubr (&Simage_metadata
);
8811 defsubr (&Slookup_image
);
8814 DEFVAR_BOOL ("cross-disabled-images", cross_disabled_images
,
8815 doc
: /* Non-nil means always draw a cross over disabled images.
8816 Disabled images are those having a `:conversion disabled' property.
8817 A cross is always drawn on black & white displays. */);
8818 cross_disabled_images
= 0;
8820 DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path
,
8821 doc
: /* List of directories to search for window system bitmap files. */);
8822 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
8824 DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay
,
8825 doc
: /* Maximum time after which images are removed from the cache.
8826 When an image has not been displayed this many seconds, Emacs
8827 automatically removes it from the image cache. If the cache contains
8828 a large number of images, the actual eviction time may be shorter.
8829 The value can also be nil, meaning the cache is never cleared.
8831 The function `clear-image-cache' disregards this variable. */);
8832 Vimage_cache_eviction_delay
= make_number (300);
8833 #ifdef HAVE_IMAGEMAGICK
8834 DEFVAR_LISP ("imagemagick-render-type", Vimagemagick_render_type
,
8835 doc
: /* Choose between ImageMagick render methods. */);