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 */
72 /* W32_TODO : Color tables on W32. */
73 #undef COLOR_TABLE_SUPPORT
75 typedef struct w32_bitmap_record Bitmap_Record
;
76 #define GET_PIXEL(ximg, x, y) GetPixel(ximg, x, y)
79 #define RGB_PIXEL_COLOR COLORREF
81 #define PIX_MASK_RETAIN 0
82 #define PIX_MASK_DRAW 1
84 #define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual
85 #define x_defined_color w32_defined_color
86 #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
88 /* Functions from w32term.c that depend on XColor (so can't go in w32term.h
89 without modifying lots of files). */
90 extern void x_query_colors (struct frame
*f
, XColor
*colors
, int ncolors
);
91 extern void x_query_color (struct frame
*f
, XColor
*color
);
93 /* Version of libpng that we were compiled with, or -1 if no PNG
94 support was compiled in. This is tested by w32-win.el to correctly
95 set up the alist used to search for PNG libraries. */
96 Lisp_Object Qlibpng_version
;
97 #endif /* HAVE_NTGUI */
101 #include <sys/types.h>
102 #include <sys/stat.h>
104 #undef COLOR_TABLE_SUPPORT
106 typedef struct ns_bitmap_record Bitmap_Record
;
108 #define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
111 #define RGB_PIXEL_COLOR unsigned long
114 #define PIX_MASK_RETAIN 0
115 #define PIX_MASK_DRAW 1
117 #define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO(f)->visual
118 #define x_defined_color(f, name, color_def, alloc) \
119 ns_defined_color (f, name, color_def, alloc, 0)
120 #define FRAME_X_SCREEN(f) 0
121 #define DefaultDepthOfScreen(screen) x_display_list->n_planes
125 /* The symbol `postscript' identifying images of this type. */
127 Lisp_Object Qpostscript
;
129 static void x_disable_image (struct frame
*, struct image
*);
130 static void x_edge_detection (struct frame
*, struct image
*, Lisp_Object
,
133 static void init_color_table (void);
134 static unsigned long lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
);
135 #ifdef COLOR_TABLE_SUPPORT
136 static void free_color_table (void);
137 static unsigned long *colors_in_color_table (int *n
);
138 static unsigned long lookup_pixel_color (struct frame
*f
, unsigned long p
);
141 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
142 id, which is just an int that this section returns. Bitmaps are
143 reference counted so they can be shared among frames.
145 Bitmap indices are guaranteed to be > 0, so a negative number can
146 be used to indicate no bitmap.
148 If you use x_create_bitmap_from_data, then you must keep track of
149 the bitmaps yourself. That is, creating a bitmap from the same
150 data more than once will not be caught. */
154 XGetImage (Display
*display
, Pixmap pixmap
, int x
, int y
,
155 unsigned int width
, unsigned int height
,
156 unsigned long plane_mask
, int format
)
158 /* TODO: not sure what this function is supposed to do.. */
159 ns_retain_object (pixmap
);
163 /* use with imgs created by ns_image_for_XPM */
165 XGetPixel (XImagePtr ximage
, int x
, int y
)
167 return ns_get_pixel (ximage
, x
, y
);
170 /* use with imgs created by ns_image_for_XPM; alpha set to 1;
171 pixel is assumed to be in form RGB */
173 XPutPixel (XImagePtr ximage
, int x
, int y
, unsigned long pixel
)
175 ns_put_pixel (ximage
, x
, y
, pixel
);
180 /* Functions to access the contents of a bitmap, given an id. */
183 x_bitmap_height (FRAME_PTR f
, int id
)
185 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
189 x_bitmap_width (FRAME_PTR f
, int id
)
191 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
194 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
196 x_bitmap_pixmap (FRAME_PTR f
, int id
)
198 return (int) FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
202 #ifdef HAVE_X_WINDOWS
204 x_bitmap_mask (FRAME_PTR f
, int id
)
206 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].mask
;
210 /* Allocate a new bitmap record. Returns index of new record. */
213 x_allocate_bitmap_record (FRAME_PTR f
)
215 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
218 if (dpyinfo
->bitmaps
== NULL
)
220 dpyinfo
->bitmaps_size
= 10;
222 = (Bitmap_Record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (Bitmap_Record
));
223 dpyinfo
->bitmaps_last
= 1;
227 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
228 return ++dpyinfo
->bitmaps_last
;
230 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
231 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
234 dpyinfo
->bitmaps_size
*= 2;
236 = (Bitmap_Record
*) xrealloc (dpyinfo
->bitmaps
,
237 dpyinfo
->bitmaps_size
* sizeof (Bitmap_Record
));
238 return ++dpyinfo
->bitmaps_last
;
241 /* Add one reference to the reference count of the bitmap with id ID. */
244 x_reference_bitmap (FRAME_PTR f
, int id
)
246 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
249 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
252 x_create_bitmap_from_data (struct frame
*f
, char *bits
, unsigned int width
, unsigned int height
)
254 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
257 #ifdef HAVE_X_WINDOWS
259 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
260 bits
, width
, height
);
263 #endif /* HAVE_X_WINDOWS */
267 bitmap
= CreateBitmap (width
, height
,
268 FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_planes
,
269 FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_cbits
,
273 #endif /* HAVE_NTGUI */
276 void *bitmap
= ns_image_from_XBM (bits
, width
, height
);
281 id
= x_allocate_bitmap_record (f
);
284 dpyinfo
->bitmaps
[id
- 1].img
= bitmap
;
285 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
288 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
289 dpyinfo
->bitmaps
[id
- 1].height
= height
;
290 dpyinfo
->bitmaps
[id
- 1].width
= width
;
291 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
293 #ifdef HAVE_X_WINDOWS
294 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
295 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
296 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
297 #endif /* HAVE_X_WINDOWS */
300 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
301 dpyinfo
->bitmaps
[id
- 1].hinst
= NULL
;
302 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
303 #endif /* HAVE_NTGUI */
308 /* Create bitmap from file FILE for frame F. */
311 x_create_bitmap_from_file (struct frame
*f
, Lisp_Object file
)
313 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
316 return -1; /* W32_TODO : bitmap support */
317 #endif /* HAVE_NTGUI */
321 void *bitmap
= ns_image_from_file (file
);
327 id
= x_allocate_bitmap_record (f
);
328 dpyinfo
->bitmaps
[id
- 1].img
= bitmap
;
329 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
330 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (SBYTES (file
) + 1);
331 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
332 dpyinfo
->bitmaps
[id
- 1].height
= ns_image_width (bitmap
);
333 dpyinfo
->bitmaps
[id
- 1].width
= ns_image_height (bitmap
);
334 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
338 #ifdef HAVE_X_WINDOWS
339 unsigned int width
, height
;
341 int xhot
, yhot
, result
, id
;
346 /* Look for an existing bitmap with the same name. */
347 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
349 if (dpyinfo
->bitmaps
[id
].refcount
350 && dpyinfo
->bitmaps
[id
].file
351 && !strcmp (dpyinfo
->bitmaps
[id
].file
, SSDATA (file
)))
353 ++dpyinfo
->bitmaps
[id
].refcount
;
358 /* Search bitmap-file-path for the file, if appropriate. */
359 fd
= openp (Vx_bitmap_file_path
, file
, Qnil
, &found
, Qnil
);
364 filename
= SSDATA (found
);
366 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
367 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
368 if (result
!= BitmapSuccess
)
371 id
= x_allocate_bitmap_record (f
);
372 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
373 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
374 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
375 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (SBYTES (file
) + 1);
376 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
377 dpyinfo
->bitmaps
[id
- 1].height
= height
;
378 dpyinfo
->bitmaps
[id
- 1].width
= width
;
379 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SSDATA (file
));
382 #endif /* HAVE_X_WINDOWS */
388 free_bitmap_record (Display_Info
*dpyinfo
, Bitmap_Record
*bm
)
390 #ifdef HAVE_X_WINDOWS
391 XFreePixmap (dpyinfo
->display
, bm
->pixmap
);
393 XFreePixmap (dpyinfo
->display
, bm
->mask
);
394 #endif /* HAVE_X_WINDOWS */
397 DeleteObject (bm
->pixmap
);
398 #endif /* HAVE_NTGUI */
401 ns_release_object (bm
->img
);
411 /* Remove reference to bitmap with id number ID. */
414 x_destroy_bitmap (FRAME_PTR f
, int id
)
416 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
420 Bitmap_Record
*bm
= &dpyinfo
->bitmaps
[id
- 1];
422 if (--bm
->refcount
== 0)
425 free_bitmap_record (dpyinfo
, bm
);
431 /* Free all the bitmaps for the display specified by DPYINFO. */
434 x_destroy_all_bitmaps (Display_Info
*dpyinfo
)
437 Bitmap_Record
*bm
= dpyinfo
->bitmaps
;
439 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++, bm
++)
440 if (bm
->refcount
> 0)
441 free_bitmap_record (dpyinfo
, bm
);
443 dpyinfo
->bitmaps_last
= 0;
447 #ifdef HAVE_X_WINDOWS
449 /* Useful functions defined in the section
450 `Image type independent image structures' below. */
452 static unsigned long four_corners_best (XImagePtr ximg
,
455 unsigned long height
);
457 static int x_create_x_image_and_pixmap (struct frame
*f
, int width
, int height
,
458 int depth
, XImagePtr
*ximg
,
461 static void x_destroy_x_image (XImagePtr ximg
);
464 /* Create a mask of a bitmap. Note is this not a perfect mask.
465 It's nicer with some borders in this context */
468 x_create_bitmap_mask (struct frame
*f
, int id
)
471 XImagePtr ximg
, mask_img
;
472 unsigned long width
, height
;
475 unsigned long x
, y
, xp
, xm
, yp
, ym
;
478 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
483 pixmap
= x_bitmap_pixmap (f
, id
);
484 width
= x_bitmap_width (f
, id
);
485 height
= x_bitmap_height (f
, id
);
488 ximg
= XGetImage (FRAME_X_DISPLAY (f
), pixmap
, 0, 0, width
, height
,
497 result
= x_create_x_image_and_pixmap (f
, width
, height
, 1, &mask_img
, &mask
);
502 XDestroyImage (ximg
);
506 bg
= four_corners_best (ximg
, NULL
, width
, height
);
508 for (y
= 0; y
< ximg
->height
; ++y
)
510 for (x
= 0; x
< ximg
->width
; ++x
)
512 xp
= x
!= ximg
->width
- 1 ? x
+ 1 : 0;
513 xm
= x
!= 0 ? x
- 1 : ximg
->width
- 1;
514 yp
= y
!= ximg
->height
- 1 ? y
+ 1 : 0;
515 ym
= y
!= 0 ? y
- 1 : ximg
->height
- 1;
516 if (XGetPixel (ximg
, x
, y
) == bg
517 && XGetPixel (ximg
, x
, yp
) == bg
518 && XGetPixel (ximg
, x
, ym
) == bg
519 && XGetPixel (ximg
, xp
, y
) == bg
520 && XGetPixel (ximg
, xp
, yp
) == bg
521 && XGetPixel (ximg
, xp
, ym
) == bg
522 && XGetPixel (ximg
, xm
, y
) == bg
523 && XGetPixel (ximg
, xm
, yp
) == bg
524 && XGetPixel (ximg
, xm
, ym
) == bg
)
525 XPutPixel (mask_img
, x
, y
, 0);
527 XPutPixel (mask_img
, x
, y
, 1);
531 xassert (interrupt_input_blocked
);
532 gc
= XCreateGC (FRAME_X_DISPLAY (f
), mask
, 0, NULL
);
533 XPutImage (FRAME_X_DISPLAY (f
), mask
, gc
, mask_img
, 0, 0, 0, 0,
535 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
537 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
538 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
540 XDestroyImage (ximg
);
541 x_destroy_x_image (mask_img
);
546 #endif /* HAVE_X_WINDOWS */
549 /***********************************************************************
551 ***********************************************************************/
553 /* Value is the number of elements of vector VECTOR. */
555 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
557 /* List of supported image types. Use define_image_type to add new
558 types. Use lookup_image_type to find a type for a given symbol. */
560 static struct image_type
*image_types
;
562 /* Cache for delayed-loading image types. */
564 static Lisp_Object Vimage_type_cache
;
566 /* The symbol `xbm' which is used as the type symbol for XBM images. */
572 Lisp_Object QCascent
, QCmargin
, QCrelief
, Qcount
, Qextension_data
;
573 Lisp_Object QCconversion
, QCcolor_symbols
, QCheuristic_mask
;
574 Lisp_Object QCindex
, QCmatrix
, QCcolor_adjustment
, QCmask
, QCgeometry
, QCcrop
, QCrotation
;
578 Lisp_Object Qlaplace
, Qemboss
, Qedge_detection
, Qheuristic
;
580 /* Function prototypes. */
582 static Lisp_Object
define_image_type (struct image_type
*type
, int loaded
);
583 static struct image_type
*lookup_image_type (Lisp_Object symbol
);
584 static void image_error (const char *format
, Lisp_Object
, Lisp_Object
);
585 static void x_laplace (struct frame
*, struct image
*);
586 static void x_emboss (struct frame
*, struct image
*);
587 static int x_build_heuristic_mask (struct frame
*, struct image
*,
590 #define CACHE_IMAGE_TYPE(type, status) \
591 do { Vimage_type_cache = Fcons (Fcons (type, status), Vimage_type_cache); } while (0)
593 #define ADD_IMAGE_TYPE(type) \
594 do { Vimage_types = Fcons (type, Vimage_types); } while (0)
596 /* Define a new image type from TYPE. This adds a copy of TYPE to
597 image_types and caches the loading status of TYPE. */
600 define_image_type (struct image_type
*type
, int loaded
)
608 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
609 The initialized data segment is read-only. */
610 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
611 memcpy (p
, type
, sizeof *p
);
612 p
->next
= image_types
;
617 CACHE_IMAGE_TYPE (*type
->type
, success
);
622 /* Look up image type SYMBOL, and return a pointer to its image_type
623 structure. Value is null if SYMBOL is not a known image type. */
625 static INLINE
struct image_type
*
626 lookup_image_type (Lisp_Object symbol
)
628 struct image_type
*type
;
630 /* We must initialize the image-type if it hasn't been already. */
631 if (NILP (Finit_image_library (symbol
, Vdynamic_library_alist
)))
632 return 0; /* unimplemented */
634 for (type
= image_types
; type
; type
= type
->next
)
635 if (EQ (symbol
, *type
->type
))
642 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
643 valid image specification is a list whose car is the symbol
644 `image', and whose rest is a property list. The property list must
645 contain a value for key `:type'. That value must be the name of a
646 supported image type. The rest of the property list depends on the
650 valid_image_p (Lisp_Object object
)
658 for (tem
= XCDR (object
); CONSP (tem
); tem
= XCDR (tem
))
659 if (EQ (XCAR (tem
), QCtype
))
662 if (CONSP (tem
) && SYMBOLP (XCAR (tem
)))
664 struct image_type
*type
;
665 type
= lookup_image_type (XCAR (tem
));
667 valid_p
= type
->valid_p (object
);
678 /* Log error message with format string FORMAT and argument ARG.
679 Signaling an error, e.g. when an image cannot be loaded, is not a
680 good idea because this would interrupt redisplay, and the error
681 message display would lead to another redisplay. This function
682 therefore simply displays a message. */
685 image_error (const char *format
, Lisp_Object arg1
, Lisp_Object arg2
)
687 add_to_log (format
, arg1
, arg2
);
692 /***********************************************************************
694 ***********************************************************************/
696 enum image_value_type
698 IMAGE_DONT_CHECK_VALUE_TYPE
,
700 IMAGE_STRING_OR_NIL_VALUE
,
702 IMAGE_POSITIVE_INTEGER_VALUE
,
703 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
,
704 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
707 IMAGE_FUNCTION_VALUE
,
712 /* Structure used when parsing image specifications. */
716 /* Name of keyword. */
719 /* The type of value allowed. */
720 enum image_value_type type
;
722 /* Non-zero means key must be present. */
725 /* Used to recognize duplicate keywords in a property list. */
728 /* The value that was found. */
733 static int parse_image_spec (Lisp_Object
, struct image_keyword
*,
735 static Lisp_Object
image_spec_value (Lisp_Object
, Lisp_Object
, int *);
738 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
739 has the format (image KEYWORD VALUE ...). One of the keyword/
740 value pairs must be `:type TYPE'. KEYWORDS is a vector of
741 image_keywords structures of size NKEYWORDS describing other
742 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
745 parse_image_spec (Lisp_Object spec
, struct image_keyword
*keywords
,
746 int nkeywords
, Lisp_Object type
)
755 while (CONSP (plist
))
757 Lisp_Object key
, value
;
759 /* First element of a pair must be a symbol. */
761 plist
= XCDR (plist
);
765 /* There must follow a value. */
768 value
= XCAR (plist
);
769 plist
= XCDR (plist
);
771 /* Find key in KEYWORDS. Error if not found. */
772 for (i
= 0; i
< nkeywords
; ++i
)
773 if (strcmp (keywords
[i
].name
, SSDATA (SYMBOL_NAME (key
))) == 0)
779 /* Record that we recognized the keyword. If a keywords
780 was found more than once, it's an error. */
781 keywords
[i
].value
= value
;
784 if (keywords
[i
].count
> 1)
787 /* Check type of value against allowed type. */
788 switch (keywords
[i
].type
)
790 case IMAGE_STRING_VALUE
:
791 if (!STRINGP (value
))
795 case IMAGE_STRING_OR_NIL_VALUE
:
796 if (!STRINGP (value
) && !NILP (value
))
800 case IMAGE_SYMBOL_VALUE
:
801 if (!SYMBOLP (value
))
805 case IMAGE_POSITIVE_INTEGER_VALUE
:
806 if (!INTEGERP (value
) || XINT (value
) <= 0)
810 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
:
811 if (INTEGERP (value
) && XINT (value
) >= 0)
814 && INTEGERP (XCAR (value
)) && INTEGERP (XCDR (value
))
815 && XINT (XCAR (value
)) >= 0 && XINT (XCDR (value
)) >= 0)
819 case IMAGE_ASCENT_VALUE
:
820 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
822 else if (INTEGERP (value
)
824 && XINT (value
) <= 100)
828 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
829 if (!INTEGERP (value
) || XINT (value
) < 0)
833 case IMAGE_DONT_CHECK_VALUE_TYPE
:
836 case IMAGE_FUNCTION_VALUE
:
837 value
= indirect_function (value
);
838 /* FIXME: Shouldn't we use Ffunctionp here? */
841 || (CONSP (value
) && EQ (XCAR (value
), Qlambda
)))
845 case IMAGE_NUMBER_VALUE
:
846 if (!INTEGERP (value
) && !FLOATP (value
))
850 case IMAGE_INTEGER_VALUE
:
851 if (!INTEGERP (value
))
855 case IMAGE_BOOL_VALUE
:
856 if (!NILP (value
) && !EQ (value
, Qt
))
865 if (EQ (key
, QCtype
) && !EQ (type
, value
))
869 /* Check that all mandatory fields are present. */
870 for (i
= 0; i
< nkeywords
; ++i
)
871 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
878 /* Return the value of KEY in image specification SPEC. Value is nil
879 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
880 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
883 image_spec_value (Lisp_Object spec
, Lisp_Object key
, int *found
)
887 xassert (valid_image_p (spec
));
889 for (tail
= XCDR (spec
);
890 CONSP (tail
) && CONSP (XCDR (tail
));
891 tail
= XCDR (XCDR (tail
)))
893 if (EQ (XCAR (tail
), key
))
897 return XCAR (XCDR (tail
));
907 DEFUN ("image-size", Fimage_size
, Simage_size
, 1, 3, 0,
908 doc
: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
909 PIXELS non-nil means return the size in pixels, otherwise return the
910 size in canonical character units.
911 FRAME is the frame on which the image will be displayed. FRAME nil
912 or omitted means use the selected frame. */)
913 (Lisp_Object spec
, Lisp_Object pixels
, Lisp_Object frame
)
918 if (valid_image_p (spec
))
920 struct frame
*f
= check_x_frame (frame
);
921 int id
= lookup_image (f
, spec
);
922 struct image
*img
= IMAGE_FROM_ID (f
, id
);
923 int width
= img
->width
+ 2 * img
->hmargin
;
924 int height
= img
->height
+ 2 * img
->vmargin
;
927 size
= Fcons (make_float ((double) width
/ FRAME_COLUMN_WIDTH (f
)),
928 make_float ((double) height
/ FRAME_LINE_HEIGHT (f
)));
930 size
= Fcons (make_number (width
), make_number (height
));
933 error ("Invalid image specification");
939 DEFUN ("image-mask-p", Fimage_mask_p
, Simage_mask_p
, 1, 2, 0,
940 doc
: /* Return t if image SPEC has a mask bitmap.
941 FRAME is the frame on which the image will be displayed. FRAME nil
942 or omitted means use the selected frame. */)
943 (Lisp_Object spec
, Lisp_Object frame
)
948 if (valid_image_p (spec
))
950 struct frame
*f
= check_x_frame (frame
);
951 int id
= lookup_image (f
, spec
);
952 struct image
*img
= IMAGE_FROM_ID (f
, id
);
957 error ("Invalid image specification");
962 DEFUN ("image-metadata", Fimage_metadata
, Simage_metadata
, 1, 2, 0,
963 doc
: /* Return metadata for image SPEC.
964 FRAME is the frame on which the image will be displayed. FRAME nil
965 or omitted means use the selected frame. */)
966 (Lisp_Object spec
, Lisp_Object frame
)
971 if (valid_image_p (spec
))
973 struct frame
*f
= check_x_frame (frame
);
974 int id
= lookup_image (f
, spec
);
975 struct image
*img
= IMAGE_FROM_ID (f
, id
);
976 ext
= img
->data
.lisp_val
;
983 /***********************************************************************
984 Image type independent image structures
985 ***********************************************************************/
987 static struct image
*make_image (Lisp_Object spec
, unsigned hash
);
988 static void free_image (struct frame
*f
, struct image
*img
);
989 static int check_image_size (struct frame
*f
, int width
, int height
);
991 #define MAX_IMAGE_SIZE 6.0
992 /* Allocate and return a new image structure for image specification
993 SPEC. SPEC has a hash value of HASH. */
995 static struct image
*
996 make_image (Lisp_Object spec
, unsigned int hash
)
998 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
999 Lisp_Object file
= image_spec_value (spec
, QCfile
, NULL
);
1001 xassert (valid_image_p (spec
));
1002 memset (img
, 0, sizeof *img
);
1003 img
->dependencies
= NILP (file
) ? Qnil
: list1 (file
);
1004 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
1005 xassert (img
->type
!= NULL
);
1007 img
->data
.lisp_val
= Qnil
;
1008 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
1010 img
->corners
[BOT_CORNER
] = -1; /* Full image */
1015 /* Free image IMG which was used on frame F, including its resources. */
1018 free_image (struct frame
*f
, struct image
*img
)
1022 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1024 /* Remove IMG from the hash table of its cache. */
1026 img
->prev
->next
= img
->next
;
1028 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
1031 img
->next
->prev
= img
->prev
;
1033 c
->images
[img
->id
] = NULL
;
1035 /* Free resources, then free IMG. */
1036 img
->type
->free (f
, img
);
1041 /* Return 1 if the given widths and heights are valid for display;
1042 otherwise, return 0. */
1045 check_image_size (struct frame
*f
, int width
, int height
)
1049 if (width
<= 0 || height
<= 0)
1052 if (INTEGERP (Vmax_image_size
))
1053 w
= h
= XINT (Vmax_image_size
);
1054 else if (FLOATP (Vmax_image_size
))
1058 w
= FRAME_PIXEL_WIDTH (f
);
1059 h
= FRAME_PIXEL_HEIGHT (f
);
1062 w
= h
= 1024; /* Arbitrary size for unknown frame. */
1063 w
= (int) (XFLOAT_DATA (Vmax_image_size
) * w
);
1064 h
= (int) (XFLOAT_DATA (Vmax_image_size
) * h
);
1069 return (width
<= w
&& height
<= h
);
1072 /* Prepare image IMG for display on frame F. Must be called before
1073 drawing an image. */
1076 prepare_image_for_display (struct frame
*f
, struct image
*img
)
1080 /* We're about to display IMG, so set its timestamp to `now'. */
1082 img
->timestamp
= EMACS_SECS (t
);
1084 /* If IMG doesn't have a pixmap yet, load it now, using the image
1085 type dependent loader function. */
1086 if (img
->pixmap
== NO_PIXMAP
&& !img
->load_failed_p
)
1087 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
1092 /* Value is the number of pixels for the ascent of image IMG when
1093 drawn in face FACE. */
1096 image_ascent (struct image
*img
, struct face
*face
, struct glyph_slice
*slice
)
1101 if (slice
->height
== img
->height
)
1102 height
= img
->height
+ img
->vmargin
;
1103 else if (slice
->y
== 0)
1104 height
= slice
->height
+ img
->vmargin
;
1106 height
= slice
->height
;
1108 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
1113 /* W32 specific version. Why?. ++kfs */
1114 ascent
= height
/ 2 - (FONT_DESCENT (face
->font
)
1115 - FONT_BASE (face
->font
)) / 2;
1117 /* This expression is arranged so that if the image can't be
1118 exactly centered, it will be moved slightly up. This is
1119 because a typical font is `top-heavy' (due to the presence
1120 uppercase letters), so the image placement should err towards
1121 being top-heavy too. It also just generally looks better. */
1122 ascent
= (height
+ FONT_BASE(face
->font
)
1123 - FONT_DESCENT(face
->font
) + 1) / 2;
1124 #endif /* HAVE_NTGUI */
1127 ascent
= height
/ 2;
1130 ascent
= (int) (height
* img
->ascent
/ 100.0);
1136 /* Image background colors. */
1138 /* Find the "best" corner color of a bitmap.
1139 On W32, XIMG is assumed to a device context with the bitmap selected. */
1141 static RGB_PIXEL_COLOR
1142 four_corners_best (XImagePtr_or_DC ximg
, int *corners
,
1143 unsigned long width
, unsigned long height
)
1145 RGB_PIXEL_COLOR corner_pixels
[4], best
;
1148 if (corners
&& corners
[BOT_CORNER
] >= 0)
1150 /* Get the colors at the corner_pixels of ximg. */
1151 corner_pixels
[0] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[TOP_CORNER
]);
1152 corner_pixels
[1] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[TOP_CORNER
]);
1153 corner_pixels
[2] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[BOT_CORNER
] - 1);
1154 corner_pixels
[3] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[BOT_CORNER
] - 1);
1158 /* Get the colors at the corner_pixels of ximg. */
1159 corner_pixels
[0] = GET_PIXEL (ximg
, 0, 0);
1160 corner_pixels
[1] = GET_PIXEL (ximg
, width
- 1, 0);
1161 corner_pixels
[2] = GET_PIXEL (ximg
, width
- 1, height
- 1);
1162 corner_pixels
[3] = GET_PIXEL (ximg
, 0, height
- 1);
1164 /* Choose the most frequently found color as background. */
1165 for (i
= best_count
= 0; i
< 4; ++i
)
1169 for (j
= n
= 0; j
< 4; ++j
)
1170 if (corner_pixels
[i
] == corner_pixels
[j
])
1174 best
= corner_pixels
[i
], best_count
= n
;
1180 /* Portability macros */
1184 #define Destroy_Image(img_dc, prev) \
1185 do { SelectObject (img_dc, prev); DeleteDC (img_dc); } while (0)
1187 #define Free_Pixmap(display, pixmap) \
1188 DeleteObject (pixmap)
1190 #elif defined (HAVE_NS)
1192 #define Destroy_Image(ximg, dummy) \
1193 ns_release_object (ximg)
1195 #define Free_Pixmap(display, pixmap) \
1196 ns_release_object (pixmap)
1200 #define Destroy_Image(ximg, dummy) \
1201 XDestroyImage (ximg)
1203 #define Free_Pixmap(display, pixmap) \
1204 XFreePixmap (display, pixmap)
1206 #endif /* !HAVE_NTGUI && !HAVE_NS */
1209 /* Return the `background' field of IMG. If IMG doesn't have one yet,
1210 it is guessed heuristically. If non-zero, XIMG is an existing
1211 XImage object (or device context with the image selected on W32) to
1212 use for the heuristic. */
1215 image_background (struct image
*img
, struct frame
*f
, XImagePtr_or_DC ximg
)
1217 if (! img
->background_valid
)
1218 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1220 int free_ximg
= !ximg
;
1223 #endif /* HAVE_NTGUI */
1228 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
1229 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
1231 HDC frame_dc
= get_frame_dc (f
);
1232 ximg
= CreateCompatibleDC (frame_dc
);
1233 release_frame_dc (f
, frame_dc
);
1234 prev
= SelectObject (ximg
, img
->pixmap
);
1235 #endif /* !HAVE_NTGUI */
1238 img
->background
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
1241 Destroy_Image (ximg
, prev
);
1243 img
->background_valid
= 1;
1246 return img
->background
;
1249 /* Return the `background_transparent' field of IMG. If IMG doesn't
1250 have one yet, it is guessed heuristically. If non-zero, MASK is an
1251 existing XImage object to use for the heuristic. */
1254 image_background_transparent (struct image
*img
, struct frame
*f
, XImagePtr_or_DC mask
)
1256 if (! img
->background_transparent_valid
)
1257 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1261 int free_mask
= !mask
;
1264 #endif /* HAVE_NTGUI */
1269 mask
= XGetImage (FRAME_X_DISPLAY (f
), img
->mask
,
1270 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
1272 HDC frame_dc
= get_frame_dc (f
);
1273 mask
= CreateCompatibleDC (frame_dc
);
1274 release_frame_dc (f
, frame_dc
);
1275 prev
= SelectObject (mask
, img
->mask
);
1276 #endif /* HAVE_NTGUI */
1279 img
->background_transparent
1280 = (four_corners_best (mask
, img
->corners
, img
->width
, img
->height
) == PIX_MASK_RETAIN
);
1283 Destroy_Image (mask
, prev
);
1286 img
->background_transparent
= 0;
1288 img
->background_transparent_valid
= 1;
1291 return img
->background_transparent
;
1295 /***********************************************************************
1296 Helper functions for X image types
1297 ***********************************************************************/
1299 static void x_clear_image_1 (struct frame
*, struct image
*, int,
1301 static void x_clear_image (struct frame
*f
, struct image
*img
);
1302 static unsigned long x_alloc_image_color (struct frame
*f
,
1304 Lisp_Object color_name
,
1305 unsigned long dflt
);
1308 /* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
1309 free the pixmap if any. MASK_P non-zero means clear the mask
1310 pixmap if any. COLORS_P non-zero means free colors allocated for
1311 the image, if any. */
1314 x_clear_image_1 (struct frame
*f
, struct image
*img
, int pixmap_p
, int mask_p
,
1317 if (pixmap_p
&& img
->pixmap
)
1319 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
1320 img
->pixmap
= NO_PIXMAP
;
1321 /* NOTE (HAVE_NS): background color is NOT an indexed color! */
1322 img
->background_valid
= 0;
1325 if (mask_p
&& img
->mask
)
1327 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
1328 img
->mask
= NO_PIXMAP
;
1329 img
->background_transparent_valid
= 0;
1332 if (colors_p
&& img
->ncolors
)
1334 /* W32_TODO: color table support. */
1335 #ifdef HAVE_X_WINDOWS
1336 x_free_colors (f
, img
->colors
, img
->ncolors
);
1337 #endif /* HAVE_X_WINDOWS */
1338 xfree (img
->colors
);
1345 /* Free X resources of image IMG which is used on frame F. */
1348 x_clear_image (struct frame
*f
, struct image
*img
)
1351 x_clear_image_1 (f
, img
, 1, 1, 1);
1356 /* Allocate color COLOR_NAME for image IMG on frame F. If color
1357 cannot be allocated, use DFLT. Add a newly allocated color to
1358 IMG->colors, so that it can be freed again. Value is the pixel
1361 static unsigned long
1362 x_alloc_image_color (struct frame
*f
, struct image
*img
, Lisp_Object color_name
,
1366 unsigned long result
;
1368 xassert (STRINGP (color_name
));
1370 if (x_defined_color (f
, SSDATA (color_name
), &color
, 1))
1372 /* This isn't called frequently so we get away with simply
1373 reallocating the color vector to the needed size, here. */
1376 (unsigned long *) xrealloc (img
->colors
,
1377 img
->ncolors
* sizeof *img
->colors
);
1378 img
->colors
[img
->ncolors
- 1] = color
.pixel
;
1379 result
= color
.pixel
;
1389 /***********************************************************************
1391 ***********************************************************************/
1393 static struct image
*search_image_cache (struct frame
*, Lisp_Object
, unsigned);
1394 static void cache_image (struct frame
*f
, struct image
*img
);
1395 static void postprocess_image (struct frame
*, struct image
*);
1397 /* Return a new, initialized image cache that is allocated from the
1398 heap. Call free_image_cache to free an image cache. */
1400 struct image_cache
*
1401 make_image_cache (void)
1403 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
1406 memset (c
, 0, sizeof *c
);
1408 c
->images
= (struct image
**) xmalloc (c
->size
* sizeof *c
->images
);
1409 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
1410 c
->buckets
= (struct image
**) xmalloc (size
);
1411 memset (c
->buckets
, 0, size
);
1416 /* Find an image matching SPEC in the cache, and return it. If no
1417 image is found, return NULL. */
1418 static struct image
*
1419 search_image_cache (struct frame
*f
, Lisp_Object spec
, unsigned int hash
)
1422 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1423 int i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1425 if (!c
) return NULL
;
1427 /* If the image spec does not specify a background color, the cached
1428 image must have the same background color as the current frame.
1429 The foreground color must also match, for the sake of monochrome
1432 In fact, we could ignore the foreground color matching condition
1433 for color images, or if the image spec specifies :foreground;
1434 similarly we could ignore the background color matching condition
1435 for formats that don't use transparency (such as jpeg), or if the
1436 image spec specifies :background. However, the extra memory
1437 usage is probably negligible in practice, so we don't bother. */
1439 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
1440 if (img
->hash
== hash
1441 && !NILP (Fequal (img
->spec
, spec
))
1442 && img
->frame_foreground
== FRAME_FOREGROUND_PIXEL (f
)
1443 && img
->frame_background
== FRAME_BACKGROUND_PIXEL (f
))
1449 /* Search frame F for an image with spec SPEC, and free it. */
1452 uncache_image (struct frame
*f
, Lisp_Object spec
)
1454 struct image
*img
= search_image_cache (f
, spec
, sxhash (spec
, 0));
1457 free_image (f
, img
);
1458 /* As display glyphs may still be referring to the image ID, we
1459 must garbage the frame (Bug#6426). */
1460 SET_FRAME_GARBAGED (f
);
1465 /* Free image cache of frame F. Be aware that X frames share images
1469 free_image_cache (struct frame
*f
)
1471 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1476 /* Cache should not be referenced by any frame when freed. */
1477 xassert (c
->refcount
== 0);
1479 for (i
= 0; i
< c
->used
; ++i
)
1480 free_image (f
, c
->images
[i
]);
1484 FRAME_IMAGE_CACHE (f
) = NULL
;
1489 /* Clear image cache of frame F. FILTER=t means free all images.
1490 FILTER=nil means clear only images that haven't been
1491 displayed for some time.
1492 Else, only free the images which have FILTER in their `dependencies'.
1493 Should be called from time to time to reduce the number of loaded images.
1494 If image-cache-eviction-delay is non-nil, this frees images in the cache
1495 which weren't displayed for at least that many seconds. */
1498 clear_image_cache (struct frame
*f
, Lisp_Object filter
)
1500 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1506 /* Block input so that we won't be interrupted by a SIGIO
1507 while being in an inconsistent state. */
1512 /* Filter image cache. */
1513 for (i
= 0; i
< c
->used
; ++i
)
1515 struct image
*img
= c
->images
[i
];
1516 if (img
&& (EQ (Qt
, filter
)
1517 || !NILP (Fmember (filter
, img
->dependencies
))))
1519 free_image (f
, img
);
1524 else if (INTEGERP (Vimage_cache_eviction_delay
))
1526 /* Free cache based on timestamp. */
1529 int delay
, nimages
= 0;
1531 for (i
= 0; i
< c
->used
; ++i
)
1535 /* If the number of cached images has grown unusually large,
1536 decrease the cache eviction delay (Bug#6230). */
1537 delay
= XFASTINT (Vimage_cache_eviction_delay
);
1539 delay
= max (1, 1600 * delay
/ (nimages
*nimages
));
1542 old
= EMACS_SECS (t
) - delay
;
1544 for (i
= 0; i
< c
->used
; ++i
)
1546 struct image
*img
= c
->images
[i
];
1547 if (img
&& img
->timestamp
< old
)
1549 free_image (f
, img
);
1555 /* We may be clearing the image cache because, for example,
1556 Emacs was iconified for a longer period of time. In that
1557 case, current matrices may still contain references to
1558 images freed above. So, clear these matrices. */
1561 Lisp_Object tail
, frame
;
1563 FOR_EACH_FRAME (tail
, frame
)
1565 struct frame
*f
= XFRAME (frame
);
1566 if (FRAME_IMAGE_CACHE (f
) == c
)
1567 clear_current_matrices (f
);
1570 ++windows_or_buffers_changed
;
1578 clear_image_caches (Lisp_Object filter
)
1580 /* FIXME: We want to do
1581 * struct terminal *t;
1582 * for (t = terminal_list; t; t = t->next_terminal)
1583 * clear_image_cache (t, filter); */
1584 Lisp_Object tail
, frame
;
1585 FOR_EACH_FRAME (tail
, frame
)
1586 if (FRAME_WINDOW_P (XFRAME (frame
)))
1587 clear_image_cache (XFRAME (frame
), filter
);
1590 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
1592 doc
: /* Clear the image cache.
1593 FILTER nil or a frame means clear all images in the selected frame.
1594 FILTER t means clear the image caches of all frames.
1595 Anything else, means only clear those images which refer to FILTER,
1596 which is then usually a filename. */)
1597 (Lisp_Object filter
)
1599 if (!(EQ (filter
, Qnil
) || FRAMEP (filter
)))
1600 clear_image_caches (filter
);
1602 clear_image_cache (check_x_frame (filter
), Qt
);
1608 DEFUN ("image-flush", Fimage_flush
, Simage_flush
,
1610 doc
: /* Fush the image with specification SPEC on frame FRAME.
1611 This removes the image from the Emacs image cache. If SPEC specifies
1612 an image file, the next redisplay of this image will read from the
1613 current contents of that file.
1615 FRAME nil or omitted means use the selected frame.
1616 FRAME t means refresh the image on all frames. */)
1617 (Lisp_Object spec
, Lisp_Object frame
)
1619 if (!valid_image_p (spec
))
1620 error ("Invalid image specification");
1625 FOR_EACH_FRAME (tail
, frame
)
1627 struct frame
*f
= XFRAME (frame
);
1628 if (FRAME_WINDOW_P (f
))
1629 uncache_image (f
, spec
);
1633 uncache_image (check_x_frame (frame
), spec
);
1639 /* Compute masks and transform image IMG on frame F, as specified
1640 by the image's specification, */
1643 postprocess_image (struct frame
*f
, struct image
*img
)
1645 /* Manipulation of the image's mask. */
1648 Lisp_Object conversion
, spec
;
1653 /* `:heuristic-mask t'
1655 means build a mask heuristically.
1656 `:heuristic-mask (R G B)'
1657 `:mask (heuristic (R G B))'
1658 means build a mask from color (R G B) in the
1661 means remove a mask, if any. */
1663 mask
= image_spec_value (spec
, QCheuristic_mask
, NULL
);
1665 x_build_heuristic_mask (f
, img
, mask
);
1670 mask
= image_spec_value (spec
, QCmask
, &found_p
);
1672 if (EQ (mask
, Qheuristic
))
1673 x_build_heuristic_mask (f
, img
, Qt
);
1674 else if (CONSP (mask
)
1675 && EQ (XCAR (mask
), Qheuristic
))
1677 if (CONSP (XCDR (mask
)))
1678 x_build_heuristic_mask (f
, img
, XCAR (XCDR (mask
)));
1680 x_build_heuristic_mask (f
, img
, XCDR (mask
));
1682 else if (NILP (mask
) && found_p
&& img
->mask
)
1684 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
1685 img
->mask
= NO_PIXMAP
;
1690 /* Should we apply an image transformation algorithm? */
1691 conversion
= image_spec_value (spec
, QCconversion
, NULL
);
1692 if (EQ (conversion
, Qdisabled
))
1693 x_disable_image (f
, img
);
1694 else if (EQ (conversion
, Qlaplace
))
1696 else if (EQ (conversion
, Qemboss
))
1698 else if (CONSP (conversion
)
1699 && EQ (XCAR (conversion
), Qedge_detection
))
1702 tem
= XCDR (conversion
);
1704 x_edge_detection (f
, img
,
1705 Fplist_get (tem
, QCmatrix
),
1706 Fplist_get (tem
, QCcolor_adjustment
));
1712 /* Return the id of image with Lisp specification SPEC on frame F.
1713 SPEC must be a valid Lisp image specification (see valid_image_p). */
1716 lookup_image (struct frame
*f
, Lisp_Object spec
)
1718 struct image_cache
*c
;
1723 /* F must be a window-system frame, and SPEC must be a valid image
1725 xassert (FRAME_WINDOW_P (f
));
1726 xassert (valid_image_p (spec
));
1728 c
= FRAME_IMAGE_CACHE (f
);
1730 /* Look up SPEC in the hash table of the image cache. */
1731 hash
= sxhash (spec
, 0);
1732 img
= search_image_cache (f
, spec
, hash
);
1733 if (img
&& img
->load_failed_p
)
1735 free_image (f
, img
);
1739 /* If not found, create a new image and cache it. */
1743 img
= make_image (spec
, hash
);
1744 cache_image (f
, img
);
1745 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
1746 img
->frame_foreground
= FRAME_FOREGROUND_PIXEL (f
);
1747 img
->frame_background
= FRAME_BACKGROUND_PIXEL (f
);
1749 /* If we can't load the image, and we don't have a width and
1750 height, use some arbitrary width and height so that we can
1751 draw a rectangle for it. */
1752 if (img
->load_failed_p
)
1756 value
= image_spec_value (spec
, QCwidth
, NULL
);
1757 img
->width
= (INTEGERP (value
)
1758 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
1759 value
= image_spec_value (spec
, QCheight
, NULL
);
1760 img
->height
= (INTEGERP (value
)
1761 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
1765 /* Handle image type independent image attributes
1766 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
1767 `:background COLOR'. */
1768 Lisp_Object ascent
, margin
, relief
, bg
;
1770 ascent
= image_spec_value (spec
, QCascent
, NULL
);
1771 if (INTEGERP (ascent
))
1772 img
->ascent
= XFASTINT (ascent
);
1773 else if (EQ (ascent
, Qcenter
))
1774 img
->ascent
= CENTERED_IMAGE_ASCENT
;
1776 margin
= image_spec_value (spec
, QCmargin
, NULL
);
1777 if (INTEGERP (margin
) && XINT (margin
) >= 0)
1778 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
1779 else if (CONSP (margin
) && INTEGERP (XCAR (margin
))
1780 && INTEGERP (XCDR (margin
)))
1782 if (XINT (XCAR (margin
)) > 0)
1783 img
->hmargin
= XFASTINT (XCAR (margin
));
1784 if (XINT (XCDR (margin
)) > 0)
1785 img
->vmargin
= XFASTINT (XCDR (margin
));
1788 relief
= image_spec_value (spec
, QCrelief
, NULL
);
1789 if (INTEGERP (relief
))
1791 img
->relief
= XINT (relief
);
1792 img
->hmargin
+= eabs (img
->relief
);
1793 img
->vmargin
+= eabs (img
->relief
);
1796 if (! img
->background_valid
)
1798 bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
1802 = x_alloc_image_color (f
, img
, bg
,
1803 FRAME_BACKGROUND_PIXEL (f
));
1804 img
->background_valid
= 1;
1808 /* Do image transformations and compute masks, unless we
1809 don't have the image yet. */
1810 if (!EQ (*img
->type
->type
, Qpostscript
))
1811 postprocess_image (f
, img
);
1817 /* We're using IMG, so set its timestamp to `now'. */
1818 EMACS_GET_TIME (now
);
1819 img
->timestamp
= EMACS_SECS (now
);
1821 /* Value is the image id. */
1826 /* Cache image IMG in the image cache of frame F. */
1829 cache_image (struct frame
*f
, struct image
*img
)
1831 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1834 /* Find a free slot in c->images. */
1835 for (i
= 0; i
< c
->used
; ++i
)
1836 if (c
->images
[i
] == NULL
)
1839 /* If no free slot found, maybe enlarge c->images. */
1840 if (i
== c
->used
&& c
->used
== c
->size
)
1843 c
->images
= (struct image
**) xrealloc (c
->images
,
1844 c
->size
* sizeof *c
->images
);
1847 /* Add IMG to c->images, and assign IMG an id. */
1853 /* Add IMG to the cache's hash table. */
1854 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1855 img
->next
= c
->buckets
[i
];
1857 img
->next
->prev
= img
;
1859 c
->buckets
[i
] = img
;
1863 /* Call FN on every image in the image cache of frame F. Used to mark
1864 Lisp Objects in the image cache. */
1866 /* Mark Lisp objects in image IMG. */
1869 mark_image (struct image
*img
)
1871 mark_object (img
->spec
);
1872 mark_object (img
->dependencies
);
1874 if (!NILP (img
->data
.lisp_val
))
1875 mark_object (img
->data
.lisp_val
);
1880 mark_image_cache (struct image_cache
*c
)
1885 for (i
= 0; i
< c
->used
; ++i
)
1887 mark_image (c
->images
[i
]);
1893 /***********************************************************************
1894 X / NS / W32 support code
1895 ***********************************************************************/
1899 /* Macro for defining functions that will be loaded from image DLLs. */
1900 #define DEF_IMGLIB_FN(rettype,func,args) rettype (FAR CDECL *fn_##func)args
1902 /* Macro for loading those image functions from the library. */
1903 #define LOAD_IMGLIB_FN(lib,func) { \
1904 fn_##func = (void *) GetProcAddress (lib, #func); \
1905 if (!fn_##func) return 0; \
1908 /* Load a DLL implementing an image type.
1909 The argument LIBRARIES is usually the variable
1910 `dynamic-library-alist', which associates a symbol, identifying
1911 an external DLL library, to a list of possible filenames.
1912 The function returns NULL if no library could be loaded for
1913 the given symbol, or if the library was previously loaded;
1914 else the handle of the DLL. */
1916 w32_delayed_load (Lisp_Object libraries
, Lisp_Object type
)
1918 HMODULE library
= NULL
;
1920 if (CONSP (libraries
) && NILP (Fassq (type
, Vimage_type_cache
)))
1922 Lisp_Object dlls
= Fassq (type
, libraries
);
1925 for (dlls
= XCDR (dlls
); CONSP (dlls
); dlls
= XCDR (dlls
))
1927 CHECK_STRING_CAR (dlls
);
1928 if (library
= LoadLibrary (SDATA (XCAR (dlls
))))
1936 #endif /* HAVE_NTGUI */
1938 static int x_create_x_image_and_pixmap (struct frame
*, int, int, int,
1939 XImagePtr
*, Pixmap
*);
1940 static void x_destroy_x_image (XImagePtr
);
1941 static void x_put_x_image (struct frame
*, XImagePtr
, Pixmap
, int, int);
1944 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
1945 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
1946 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
1947 via xmalloc. Print error messages via image_error if an error
1948 occurs. Value is non-zero if successful.
1950 On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
1951 should indicate the bit depth of the image. */
1954 x_create_x_image_and_pixmap (struct frame
*f
, int width
, int height
, int depth
,
1955 XImagePtr
*ximg
, Pixmap
*pixmap
)
1957 #ifdef HAVE_X_WINDOWS
1958 Display
*display
= FRAME_X_DISPLAY (f
);
1959 Window window
= FRAME_X_WINDOW (f
);
1960 Screen
*screen
= FRAME_X_SCREEN (f
);
1962 xassert (interrupt_input_blocked
);
1965 depth
= DefaultDepthOfScreen (screen
);
1966 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
1967 depth
, ZPixmap
, 0, NULL
, width
, height
,
1968 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
1971 image_error ("Unable to allocate X image", Qnil
, Qnil
);
1975 /* Allocate image raster. */
1976 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
1978 /* Allocate a pixmap of the same size. */
1979 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
1980 if (*pixmap
== NO_PIXMAP
)
1982 x_destroy_x_image (*ximg
);
1984 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
1989 #endif /* HAVE_X_WINDOWS */
1993 BITMAPINFOHEADER
*header
;
1995 int scanline_width_bits
;
1997 int palette_colors
= 0;
2002 if (depth
!= 1 && depth
!= 4 && depth
!= 8
2003 && depth
!= 16 && depth
!= 24 && depth
!= 32)
2005 image_error ("Invalid image bit depth specified", Qnil
, Qnil
);
2009 scanline_width_bits
= width
* depth
;
2010 remainder
= scanline_width_bits
% 32;
2013 scanline_width_bits
+= 32 - remainder
;
2015 /* Bitmaps with a depth less than 16 need a palette. */
2016 /* BITMAPINFO structure already contains the first RGBQUAD. */
2018 palette_colors
= 1 << depth
- 1;
2020 *ximg
= xmalloc (sizeof (XImage
) + palette_colors
* sizeof (RGBQUAD
));
2023 image_error ("Unable to allocate memory for XImage", Qnil
, Qnil
);
2027 header
= &(*ximg
)->info
.bmiHeader
;
2028 memset (&(*ximg
)->info
, 0, sizeof (BITMAPINFO
));
2029 header
->biSize
= sizeof (*header
);
2030 header
->biWidth
= width
;
2031 header
->biHeight
= -height
; /* negative indicates a top-down bitmap. */
2032 header
->biPlanes
= 1;
2033 header
->biBitCount
= depth
;
2034 header
->biCompression
= BI_RGB
;
2035 header
->biClrUsed
= palette_colors
;
2037 /* TODO: fill in palette. */
2040 (*ximg
)->info
.bmiColors
[0].rgbBlue
= 0;
2041 (*ximg
)->info
.bmiColors
[0].rgbGreen
= 0;
2042 (*ximg
)->info
.bmiColors
[0].rgbRed
= 0;
2043 (*ximg
)->info
.bmiColors
[0].rgbReserved
= 0;
2044 (*ximg
)->info
.bmiColors
[1].rgbBlue
= 255;
2045 (*ximg
)->info
.bmiColors
[1].rgbGreen
= 255;
2046 (*ximg
)->info
.bmiColors
[1].rgbRed
= 255;
2047 (*ximg
)->info
.bmiColors
[1].rgbReserved
= 0;
2050 hdc
= get_frame_dc (f
);
2052 /* Create a DIBSection and raster array for the bitmap,
2053 and store its handle in *pixmap. */
2054 *pixmap
= CreateDIBSection (hdc
, &((*ximg
)->info
),
2055 (depth
< 16) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
,
2056 /* casting avoids a GCC warning */
2057 (void **)&((*ximg
)->data
), NULL
, 0);
2059 /* Realize display palette and garbage all frames. */
2060 release_frame_dc (f
, hdc
);
2062 if (*pixmap
== NULL
)
2064 DWORD err
= GetLastError ();
2065 Lisp_Object errcode
;
2066 /* All system errors are < 10000, so the following is safe. */
2067 XSETINT (errcode
, (int) err
);
2068 image_error ("Unable to create bitmap, error code %d", errcode
, Qnil
);
2069 x_destroy_x_image (*ximg
);
2075 #endif /* HAVE_NTGUI */
2078 *pixmap
= ns_image_for_XPM (width
, height
, depth
);
2082 image_error ("Unable to allocate NSImage for XPM pixmap", Qnil
, Qnil
);
2091 /* Destroy XImage XIMG. Free XIMG->data. */
2094 x_destroy_x_image (XImagePtr ximg
)
2096 xassert (interrupt_input_blocked
);
2099 #ifdef HAVE_X_WINDOWS
2102 XDestroyImage (ximg
);
2103 #endif /* HAVE_X_WINDOWS */
2105 /* Data will be freed by DestroyObject. */
2108 #endif /* HAVE_NTGUI */
2110 ns_release_object (ximg
);
2111 #endif /* HAVE_NS */
2116 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
2117 are width and height of both the image and pixmap. */
2120 x_put_x_image (struct frame
*f
, XImagePtr ximg
, Pixmap pixmap
, int width
, int height
)
2122 #ifdef HAVE_X_WINDOWS
2125 xassert (interrupt_input_blocked
);
2126 gc
= XCreateGC (FRAME_X_DISPLAY (f
), pixmap
, 0, NULL
);
2127 XPutImage (FRAME_X_DISPLAY (f
), pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
2128 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
2129 #endif /* HAVE_X_WINDOWS */
2132 #if 0 /* I don't think this is necessary looking at where it is used. */
2133 HDC hdc
= get_frame_dc (f
);
2134 SetDIBits (hdc
, pixmap
, 0, height
, ximg
->data
, &(ximg
->info
), DIB_RGB_COLORS
);
2135 release_frame_dc (f
, hdc
);
2137 #endif /* HAVE_NTGUI */
2140 xassert (ximg
== pixmap
);
2141 ns_retain_object (ximg
);
2146 /***********************************************************************
2148 ***********************************************************************/
2150 static unsigned char *slurp_file (char *, int *);
2153 /* Find image file FILE. Look in data-directory/images, then
2154 x-bitmap-file-path. Value is the encoded full name of the file
2155 found, or nil if not found. */
2158 x_find_image_file (Lisp_Object file
)
2160 Lisp_Object file_found
, search_path
;
2163 /* TODO I think this should use something like image-load-path
2164 instead. Unfortunately, that can contain non-string elements. */
2165 search_path
= Fcons (Fexpand_file_name (build_string ("images"),
2167 Vx_bitmap_file_path
);
2169 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
2170 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
2176 file_found
= ENCODE_FILE (file_found
);
2184 /* Read FILE into memory. Value is a pointer to a buffer allocated
2185 with xmalloc holding FILE's contents. Value is null if an error
2186 occurred. *SIZE is set to the size of the file. */
2188 static unsigned char *
2189 slurp_file (char *file
, int *size
)
2192 unsigned char *buf
= NULL
;
2195 if (stat (file
, &st
) == 0
2196 && (fp
= fopen (file
, "rb")) != NULL
2197 && (buf
= (unsigned char *) xmalloc (st
.st_size
),
2198 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
2219 /***********************************************************************
2221 ***********************************************************************/
2223 static int xbm_scan (unsigned char **, unsigned char *, char *, int *);
2224 static int xbm_load (struct frame
*f
, struct image
*img
);
2225 static int xbm_load_image (struct frame
*f
, struct image
*img
,
2226 unsigned char *, unsigned char *);
2227 static int xbm_image_p (Lisp_Object object
);
2228 static int xbm_read_bitmap_data (struct frame
*f
,
2229 unsigned char *, unsigned char *,
2230 int *, int *, char **, int);
2231 static int xbm_file_p (Lisp_Object
);
2234 /* Indices of image specification fields in xbm_format, below. */
2236 enum xbm_keyword_index
2254 /* Vector of image_keyword structures describing the format
2255 of valid XBM image specifications. */
2257 static const struct image_keyword xbm_format
[XBM_LAST
] =
2259 {":type", IMAGE_SYMBOL_VALUE
, 1},
2260 {":file", IMAGE_STRING_VALUE
, 0},
2261 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2262 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2263 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2264 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
2265 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
2266 {":ascent", IMAGE_ASCENT_VALUE
, 0},
2267 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
2268 {":relief", IMAGE_INTEGER_VALUE
, 0},
2269 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2270 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2271 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
2274 /* Structure describing the image type XBM. */
2276 static struct image_type xbm_type
=
2285 /* Tokens returned from xbm_scan. */
2294 /* Return non-zero if OBJECT is a valid XBM-type image specification.
2295 A valid specification is a list starting with the symbol `image'
2296 The rest of the list is a property list which must contain an
2299 If the specification specifies a file to load, it must contain
2300 an entry `:file FILENAME' where FILENAME is a string.
2302 If the specification is for a bitmap loaded from memory it must
2303 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
2304 WIDTH and HEIGHT are integers > 0. DATA may be:
2306 1. a string large enough to hold the bitmap data, i.e. it must
2307 have a size >= (WIDTH + 7) / 8 * HEIGHT
2309 2. a bool-vector of size >= WIDTH * HEIGHT
2311 3. a vector of strings or bool-vectors, one for each line of the
2314 4. a string containing an in-memory XBM file. WIDTH and HEIGHT
2315 may not be specified in this case because they are defined in the
2318 Both the file and data forms may contain the additional entries
2319 `:background COLOR' and `:foreground COLOR'. If not present,
2320 foreground and background of the frame on which the image is
2321 displayed is used. */
2324 xbm_image_p (Lisp_Object object
)
2326 struct image_keyword kw
[XBM_LAST
];
2328 memcpy (kw
, xbm_format
, sizeof kw
);
2329 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
2332 xassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
2334 if (kw
[XBM_FILE
].count
)
2336 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
2339 else if (kw
[XBM_DATA
].count
&& xbm_file_p (kw
[XBM_DATA
].value
))
2341 /* In-memory XBM file. */
2342 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_FILE
].count
)
2350 /* Entries for `:width', `:height' and `:data' must be present. */
2351 if (!kw
[XBM_WIDTH
].count
2352 || !kw
[XBM_HEIGHT
].count
2353 || !kw
[XBM_DATA
].count
)
2356 data
= kw
[XBM_DATA
].value
;
2357 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
2358 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
2360 /* Check type of data, and width and height against contents of
2366 /* Number of elements of the vector must be >= height. */
2367 if (XVECTOR (data
)->size
< height
)
2370 /* Each string or bool-vector in data must be large enough
2371 for one line of the image. */
2372 for (i
= 0; i
< height
; ++i
)
2374 Lisp_Object elt
= XVECTOR (data
)->contents
[i
];
2379 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
2382 else if (BOOL_VECTOR_P (elt
))
2384 if (XBOOL_VECTOR (elt
)->size
< width
)
2391 else if (STRINGP (data
))
2394 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
2397 else if (BOOL_VECTOR_P (data
))
2399 if (XBOOL_VECTOR (data
)->size
< width
* height
)
2410 /* Scan a bitmap file. FP is the stream to read from. Value is
2411 either an enumerator from enum xbm_token, or a character for a
2412 single-character token, or 0 at end of file. If scanning an
2413 identifier, store the lexeme of the identifier in SVAL. If
2414 scanning a number, store its value in *IVAL. */
2417 xbm_scan (unsigned char **s
, unsigned char *end
, char *sval
, int *ival
)
2423 /* Skip white space. */
2424 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
2429 else if (isdigit (c
))
2431 int value
= 0, digit
;
2433 if (c
== '0' && *s
< end
)
2436 if (c
== 'x' || c
== 'X')
2443 else if (c
>= 'a' && c
<= 'f')
2444 digit
= c
- 'a' + 10;
2445 else if (c
>= 'A' && c
<= 'F')
2446 digit
= c
- 'A' + 10;
2449 value
= 16 * value
+ digit
;
2452 else if (isdigit (c
))
2456 && (c
= *(*s
)++, isdigit (c
)))
2457 value
= 8 * value
+ c
- '0';
2464 && (c
= *(*s
)++, isdigit (c
)))
2465 value
= 10 * value
+ c
- '0';
2473 else if (isalpha (c
) || c
== '_')
2477 && (c
= *(*s
)++, (isalnum (c
) || c
== '_')))
2484 else if (c
== '/' && **s
== '*')
2486 /* C-style comment. */
2488 while (**s
&& (**s
!= '*' || *(*s
+ 1) != '/'))
2502 /* Create a Windows bitmap from X bitmap data. */
2504 w32_create_pixmap_from_bitmap_data (int width
, int height
, char *data
)
2506 static unsigned char swap_nibble
[16]
2507 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
2508 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
2509 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
2510 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
2512 unsigned char *bits
, *p
;
2515 w1
= (width
+ 7) / 8; /* nb of 8bits elt in X bitmap */
2516 w2
= ((width
+ 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
2517 bits
= (unsigned char *) alloca (height
* w2
);
2518 memset (bits
, 0, height
* w2
);
2519 for (i
= 0; i
< height
; i
++)
2522 for (j
= 0; j
< w1
; j
++)
2524 /* Bitswap XBM bytes to match how Windows does things. */
2525 unsigned char c
= *data
++;
2526 *p
++ = (unsigned char)((swap_nibble
[c
& 0xf] << 4)
2527 | (swap_nibble
[(c
>>4) & 0xf]));
2530 bmp
= CreateBitmap (width
, height
, 1, 1, (char *) bits
);
2536 convert_mono_to_color_image (struct frame
*f
, struct image
*img
,
2537 COLORREF foreground
, COLORREF background
)
2539 HDC hdc
, old_img_dc
, new_img_dc
;
2540 HGDIOBJ old_prev
, new_prev
;
2543 hdc
= get_frame_dc (f
);
2544 old_img_dc
= CreateCompatibleDC (hdc
);
2545 new_img_dc
= CreateCompatibleDC (hdc
);
2546 new_pixmap
= CreateCompatibleBitmap (hdc
, img
->width
, img
->height
);
2547 release_frame_dc (f
, hdc
);
2548 old_prev
= SelectObject (old_img_dc
, img
->pixmap
);
2549 new_prev
= SelectObject (new_img_dc
, new_pixmap
);
2550 /* Windows convention for mono bitmaps is black = background,
2551 white = foreground. */
2552 SetTextColor (new_img_dc
, background
);
2553 SetBkColor (new_img_dc
, foreground
);
2555 BitBlt (new_img_dc
, 0, 0, img
->width
, img
->height
, old_img_dc
,
2558 SelectObject (old_img_dc
, old_prev
);
2559 SelectObject (new_img_dc
, new_prev
);
2560 DeleteDC (old_img_dc
);
2561 DeleteDC (new_img_dc
);
2562 DeleteObject (img
->pixmap
);
2563 if (new_pixmap
== 0)
2564 fprintf (stderr
, "Failed to convert image to color.\n");
2566 img
->pixmap
= new_pixmap
;
2569 #define XBM_BIT_SHUFFLE(b) (~(b))
2573 #define XBM_BIT_SHUFFLE(b) (b)
2575 #endif /* HAVE_NTGUI */
2579 Create_Pixmap_From_Bitmap_Data (struct frame
*f
, struct image
*img
, char *data
,
2580 RGB_PIXEL_COLOR fg
, RGB_PIXEL_COLOR bg
,
2581 int non_default_colors
)
2585 = w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
, data
);
2587 /* If colors were specified, transfer the bitmap to a color one. */
2588 if (non_default_colors
)
2589 convert_mono_to_color_image (f
, img
, fg
, bg
);
2591 #elif defined (HAVE_NS)
2592 img
->pixmap
= ns_image_from_XBM (data
, img
->width
, img
->height
);
2596 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
2599 img
->width
, img
->height
,
2601 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
2602 #endif /* !HAVE_NTGUI && !HAVE_NS */
2607 /* Replacement for XReadBitmapFileData which isn't available under old
2608 X versions. CONTENTS is a pointer to a buffer to parse; END is the
2609 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
2610 the image. Return in *DATA the bitmap data allocated with xmalloc.
2611 Value is non-zero if successful. DATA null means just test if
2612 CONTENTS looks like an in-memory XBM file. If INHIBIT_IMAGE_ERROR
2613 is non-zero, inhibit the call to image_error when the image size is
2614 invalid (the bitmap remains unread). */
2617 xbm_read_bitmap_data (struct frame
*f
, unsigned char *contents
, unsigned char *end
,
2618 int *width
, int *height
, char **data
,
2619 int inhibit_image_error
)
2621 unsigned char *s
= contents
;
2622 char buffer
[BUFSIZ
];
2625 int bytes_per_line
, i
, nbytes
;
2631 LA1 = xbm_scan (&s, end, buffer, &value)
2633 #define expect(TOKEN) \
2634 if (LA1 != (TOKEN)) \
2639 #define expect_ident(IDENT) \
2640 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
2645 *width
= *height
= -1;
2648 LA1
= xbm_scan (&s
, end
, buffer
, &value
);
2650 /* Parse defines for width, height and hot-spots. */
2654 expect_ident ("define");
2655 expect (XBM_TK_IDENT
);
2657 if (LA1
== XBM_TK_NUMBER
)
2659 char *p
= strrchr (buffer
, '_');
2660 p
= p
? p
+ 1 : buffer
;
2661 if (strcmp (p
, "width") == 0)
2663 else if (strcmp (p
, "height") == 0)
2666 expect (XBM_TK_NUMBER
);
2669 if (!check_image_size (f
, *width
, *height
))
2671 if (!inhibit_image_error
)
2672 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
2675 else if (data
== NULL
)
2678 /* Parse bits. Must start with `static'. */
2679 expect_ident ("static");
2680 if (LA1
== XBM_TK_IDENT
)
2682 if (strcmp (buffer
, "unsigned") == 0)
2685 expect_ident ("char");
2687 else if (strcmp (buffer
, "short") == 0)
2691 if (*width
% 16 && *width
% 16 < 9)
2694 else if (strcmp (buffer
, "char") == 0)
2702 expect (XBM_TK_IDENT
);
2708 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
2709 nbytes
= bytes_per_line
* *height
;
2710 p
= *data
= (char *) xmalloc (nbytes
);
2714 for (i
= 0; i
< nbytes
; i
+= 2)
2717 expect (XBM_TK_NUMBER
);
2719 *p
++ = XBM_BIT_SHUFFLE (val
);
2720 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
2721 *p
++ = XBM_BIT_SHUFFLE (value
>> 8);
2723 if (LA1
== ',' || LA1
== '}')
2731 for (i
= 0; i
< nbytes
; ++i
)
2734 expect (XBM_TK_NUMBER
);
2736 *p
++ = XBM_BIT_SHUFFLE (val
);
2738 if (LA1
== ',' || LA1
== '}')
2763 /* Load XBM image IMG which will be displayed on frame F from buffer
2764 CONTENTS. END is the end of the buffer. Value is non-zero if
2768 xbm_load_image (struct frame
*f
, struct image
*img
, unsigned char *contents
,
2775 rc
= xbm_read_bitmap_data (f
, contents
, end
, &img
->width
, &img
->height
,
2779 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2780 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2781 int non_default_colors
= 0;
2784 xassert (img
->width
> 0 && img
->height
> 0);
2786 /* Get foreground and background colors, maybe allocate colors. */
2787 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
2790 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
2791 non_default_colors
= 1;
2793 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
2796 background
= x_alloc_image_color (f
, img
, value
, background
);
2797 img
->background
= background
;
2798 img
->background_valid
= 1;
2799 non_default_colors
= 1;
2802 Create_Pixmap_From_Bitmap_Data (f
, img
, data
,
2803 foreground
, background
,
2804 non_default_colors
);
2807 if (img
->pixmap
== NO_PIXMAP
)
2809 x_clear_image (f
, img
);
2810 image_error ("Unable to create X pixmap for `%s'", img
->spec
, Qnil
);
2816 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
2822 /* Value is non-zero if DATA looks like an in-memory XBM file. */
2825 xbm_file_p (Lisp_Object data
)
2828 return (STRINGP (data
)
2829 && xbm_read_bitmap_data (NULL
, SDATA (data
),
2830 (SDATA (data
) + SBYTES (data
)),
2835 /* Fill image IMG which is used on frame F with pixmap data. Value is
2836 non-zero if successful. */
2839 xbm_load (struct frame
*f
, struct image
*img
)
2842 Lisp_Object file_name
;
2844 xassert (xbm_image_p (img
->spec
));
2846 /* If IMG->spec specifies a file name, create a non-file spec from it. */
2847 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
2848 if (STRINGP (file_name
))
2851 unsigned char *contents
;
2854 file
= x_find_image_file (file_name
);
2855 if (!STRINGP (file
))
2857 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
2861 contents
= slurp_file (SSDATA (file
), &size
);
2862 if (contents
== NULL
)
2864 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
2868 success_p
= xbm_load_image (f
, img
, contents
, contents
+ size
);
2872 struct image_keyword fmt
[XBM_LAST
];
2874 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2875 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2876 int non_default_colors
= 0;
2879 int in_memory_file_p
= 0;
2881 /* See if data looks like an in-memory XBM file. */
2882 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
2883 in_memory_file_p
= xbm_file_p (data
);
2885 /* Parse the image specification. */
2886 memcpy (fmt
, xbm_format
, sizeof fmt
);
2887 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
2890 /* Get specified width, and height. */
2891 if (!in_memory_file_p
)
2893 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
2894 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
2895 xassert (img
->width
> 0 && img
->height
> 0);
2898 /* Get foreground and background colors, maybe allocate colors. */
2899 if (fmt
[XBM_FOREGROUND
].count
2900 && STRINGP (fmt
[XBM_FOREGROUND
].value
))
2902 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
2904 non_default_colors
= 1;
2907 if (fmt
[XBM_BACKGROUND
].count
2908 && STRINGP (fmt
[XBM_BACKGROUND
].value
))
2910 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
2912 non_default_colors
= 1;
2915 if (in_memory_file_p
)
2916 success_p
= xbm_load_image (f
, img
, SDATA (data
),
2925 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
2927 p
= bits
= (char *) alloca (nbytes
* img
->height
);
2928 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
2930 Lisp_Object line
= XVECTOR (data
)->contents
[i
];
2932 memcpy (p
, SDATA (line
), nbytes
);
2934 memcpy (p
, XBOOL_VECTOR (line
)->data
, nbytes
);
2937 else if (STRINGP (data
))
2938 bits
= SSDATA (data
);
2940 bits
= (char *) XBOOL_VECTOR (data
)->data
;
2946 /* Windows mono bitmaps are reversed compared with X. */
2947 invertedBits
= bits
;
2948 nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
2950 bits
= (char *) alloca (nbytes
);
2951 for (i
= 0; i
< nbytes
; i
++)
2952 bits
[i
] = XBM_BIT_SHUFFLE (invertedBits
[i
]);
2955 /* Create the pixmap. */
2957 Create_Pixmap_From_Bitmap_Data (f
, img
, bits
,
2958 foreground
, background
,
2959 non_default_colors
);
2964 image_error ("Unable to create pixmap for XBM image `%s'",
2966 x_clear_image (f
, img
);
2976 /***********************************************************************
2978 ***********************************************************************/
2980 #if defined (HAVE_XPM) || defined (HAVE_NS)
2982 static int xpm_image_p (Lisp_Object object
);
2983 static int xpm_load (struct frame
*f
, struct image
*img
);
2984 static int xpm_valid_color_symbols_p (Lisp_Object
);
2986 #endif /* HAVE_XPM || HAVE_NS */
2990 /* Indicate to xpm.h that we don't have Xlib. */
2992 /* simx.h in xpm defines XColor and XImage differently than Emacs. */
2993 /* It also defines Display the same way as Emacs, but gcc 3.3 still barfs. */
2994 #define XColor xpm_XColor
2995 #define XImage xpm_XImage
2996 #define Display xpm_Display
2997 #define PIXEL_ALREADY_TYPEDEFED
2998 #include "X11/xpm.h"
3003 #undef PIXEL_ALREADY_TYPEDEFED
3005 #include "X11/xpm.h"
3006 #endif /* HAVE_NTGUI */
3007 #endif /* HAVE_XPM */
3009 #if defined (HAVE_XPM) || defined (HAVE_NS)
3010 /* The symbol `xpm' identifying XPM-format images. */
3014 /* Indices of image specification fields in xpm_format, below. */
3016 enum xpm_keyword_index
3032 /* Vector of image_keyword structures describing the format
3033 of valid XPM image specifications. */
3035 static const struct image_keyword xpm_format
[XPM_LAST
] =
3037 {":type", IMAGE_SYMBOL_VALUE
, 1},
3038 {":file", IMAGE_STRING_VALUE
, 0},
3039 {":data", IMAGE_STRING_VALUE
, 0},
3040 {":ascent", IMAGE_ASCENT_VALUE
, 0},
3041 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
3042 {":relief", IMAGE_INTEGER_VALUE
, 0},
3043 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3044 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3045 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3046 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3047 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
3050 /* Structure describing the image type XPM. */
3052 static struct image_type xpm_type
=
3061 #ifdef HAVE_X_WINDOWS
3063 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
3064 functions for allocating image colors. Our own functions handle
3065 color allocation failures more gracefully than the ones on the XPM
3068 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
3069 #define ALLOC_XPM_COLORS
3071 #endif /* HAVE_X_WINDOWS */
3073 #ifdef ALLOC_XPM_COLORS
3075 static void xpm_init_color_cache (struct frame
*, XpmAttributes
*);
3076 static void xpm_free_color_cache (void);
3077 static int xpm_lookup_color (struct frame
*, char *, XColor
*);
3078 static int xpm_color_bucket (char *);
3079 static struct xpm_cached_color
*xpm_cache_color (struct frame
*, char *,
3082 /* An entry in a hash table used to cache color definitions of named
3083 colors. This cache is necessary to speed up XPM image loading in
3084 case we do color allocations ourselves. Without it, we would need
3085 a call to XParseColor per pixel in the image. */
3087 struct xpm_cached_color
3089 /* Next in collision chain. */
3090 struct xpm_cached_color
*next
;
3092 /* Color definition (RGB and pixel color). */
3099 /* The hash table used for the color cache, and its bucket vector
3102 #define XPM_COLOR_CACHE_BUCKETS 1001
3103 struct xpm_cached_color
**xpm_color_cache
;
3105 /* Initialize the color cache. */
3108 xpm_init_color_cache (struct frame
*f
, XpmAttributes
*attrs
)
3110 size_t nbytes
= XPM_COLOR_CACHE_BUCKETS
* sizeof *xpm_color_cache
;
3111 xpm_color_cache
= (struct xpm_cached_color
**) xmalloc (nbytes
);
3112 memset (xpm_color_cache
, 0, nbytes
);
3113 init_color_table ();
3115 if (attrs
->valuemask
& XpmColorSymbols
)
3120 for (i
= 0; i
< attrs
->numsymbols
; ++i
)
3121 if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
3122 attrs
->colorsymbols
[i
].value
, &color
))
3124 color
.pixel
= lookup_rgb_color (f
, color
.red
, color
.green
,
3126 xpm_cache_color (f
, attrs
->colorsymbols
[i
].name
, &color
, -1);
3131 /* Free the color cache. */
3134 xpm_free_color_cache (void)
3136 struct xpm_cached_color
*p
, *next
;
3139 for (i
= 0; i
< XPM_COLOR_CACHE_BUCKETS
; ++i
)
3140 for (p
= xpm_color_cache
[i
]; p
; p
= next
)
3146 xfree (xpm_color_cache
);
3147 xpm_color_cache
= NULL
;
3148 free_color_table ();
3151 /* Return the bucket index for color named COLOR_NAME in the color
3155 xpm_color_bucket (char *color_name
)
3160 for (s
= color_name
; *s
; ++s
)
3162 return h
%= XPM_COLOR_CACHE_BUCKETS
;
3166 /* On frame F, cache values COLOR for color with name COLOR_NAME.
3167 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
3170 static struct xpm_cached_color
*
3171 xpm_cache_color (struct frame
*f
, char *color_name
, XColor
*color
, int bucket
)
3174 struct xpm_cached_color
*p
;
3177 bucket
= xpm_color_bucket (color_name
);
3179 nbytes
= sizeof *p
+ strlen (color_name
);
3180 p
= (struct xpm_cached_color
*) xmalloc (nbytes
);
3181 strcpy (p
->name
, color_name
);
3183 p
->next
= xpm_color_cache
[bucket
];
3184 xpm_color_cache
[bucket
] = p
;
3188 /* Look up color COLOR_NAME for frame F in the color cache. If found,
3189 return the cached definition in *COLOR. Otherwise, make a new
3190 entry in the cache and allocate the color. Value is zero if color
3191 allocation failed. */
3194 xpm_lookup_color (struct frame
*f
, char *color_name
, XColor
*color
)
3196 struct xpm_cached_color
*p
;
3197 int h
= xpm_color_bucket (color_name
);
3199 for (p
= xpm_color_cache
[h
]; p
; p
= p
->next
)
3200 if (strcmp (p
->name
, color_name
) == 0)
3205 else if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
3208 color
->pixel
= lookup_rgb_color (f
, color
->red
, color
->green
,
3210 p
= xpm_cache_color (f
, color_name
, color
, h
);
3212 /* You get `opaque' at least from ImageMagick converting pbm to xpm
3213 with transparency, and it's useful. */
3214 else if (strcmp ("opaque", color_name
) == 0)
3216 memset (color
, 0, sizeof (XColor
)); /* Is this necessary/correct? */
3217 color
->pixel
= FRAME_FOREGROUND_PIXEL (f
);
3218 p
= xpm_cache_color (f
, color_name
, color
, h
);
3225 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
3226 CLOSURE is a pointer to the frame on which we allocate the
3227 color. Return in *COLOR the allocated color. Value is non-zero
3231 xpm_alloc_color (Display
*dpy
, Colormap cmap
, char *color_name
, XColor
*color
,
3234 return xpm_lookup_color ((struct frame
*) closure
, color_name
, color
);
3238 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
3239 is a pointer to the frame on which we allocate the color. Value is
3240 non-zero if successful. */
3243 xpm_free_colors (Display
*dpy
, Colormap cmap
, Pixel
*pixels
, int npixels
, void *closure
)
3248 #endif /* ALLOC_XPM_COLORS */
3253 /* XPM library details. */
3255 DEF_IMGLIB_FN (void, XpmFreeAttributes
, (XpmAttributes
*));
3256 DEF_IMGLIB_FN (int, XpmCreateImageFromBuffer
, (Display
*, char *, xpm_XImage
**,
3257 xpm_XImage
**, XpmAttributes
*));
3258 DEF_IMGLIB_FN (int, XpmReadFileToImage
, (Display
*, char *, xpm_XImage
**,
3259 xpm_XImage
**, XpmAttributes
*));
3260 DEF_IMGLIB_FN (void, XImageFree
, (xpm_XImage
*));
3263 init_xpm_functions (Lisp_Object libraries
)
3267 if (!(library
= w32_delayed_load (libraries
, Qxpm
)))
3270 LOAD_IMGLIB_FN (library
, XpmFreeAttributes
);
3271 LOAD_IMGLIB_FN (library
, XpmCreateImageFromBuffer
);
3272 LOAD_IMGLIB_FN (library
, XpmReadFileToImage
);
3273 LOAD_IMGLIB_FN (library
, XImageFree
);
3277 #endif /* HAVE_NTGUI */
3280 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
3281 for XPM images. Such a list must consist of conses whose car and
3285 xpm_valid_color_symbols_p (Lisp_Object color_symbols
)
3287 while (CONSP (color_symbols
))
3289 Lisp_Object sym
= XCAR (color_symbols
);
3291 || !STRINGP (XCAR (sym
))
3292 || !STRINGP (XCDR (sym
)))
3294 color_symbols
= XCDR (color_symbols
);
3297 return NILP (color_symbols
);
3301 /* Value is non-zero if OBJECT is a valid XPM image specification. */
3304 xpm_image_p (Lisp_Object object
)
3306 struct image_keyword fmt
[XPM_LAST
];
3307 memcpy (fmt
, xpm_format
, sizeof fmt
);
3308 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
3309 /* Either `:file' or `:data' must be present. */
3310 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
3311 /* Either no `:color-symbols' or it's a list of conses
3312 whose car and cdr are strings. */
3313 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
3314 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
)));
3317 #endif /* HAVE_XPM || HAVE_NS */
3319 #if defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
3321 x_create_bitmap_from_xpm_data (struct frame
*f
, const char **bits
)
3323 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3325 XpmAttributes attrs
;
3326 Pixmap bitmap
, mask
;
3328 memset (&attrs
, 0, sizeof attrs
);
3330 attrs
.visual
= FRAME_X_VISUAL (f
);
3331 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3332 attrs
.valuemask
|= XpmVisual
;
3333 attrs
.valuemask
|= XpmColormap
;
3335 rc
= XpmCreatePixmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3336 (char **) bits
, &bitmap
, &mask
, &attrs
);
3337 if (rc
!= XpmSuccess
)
3339 XpmFreeAttributes (&attrs
);
3343 id
= x_allocate_bitmap_record (f
);
3344 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
3345 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
3346 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
3347 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
3348 dpyinfo
->bitmaps
[id
- 1].height
= attrs
.height
;
3349 dpyinfo
->bitmaps
[id
- 1].width
= attrs
.width
;
3350 dpyinfo
->bitmaps
[id
- 1].depth
= attrs
.depth
;
3351 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
3353 XpmFreeAttributes (&attrs
);
3356 #endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */
3358 /* Load image IMG which will be displayed on frame F. Value is
3359 non-zero if successful. */
3364 xpm_load (struct frame
*f
, struct image
*img
)
3367 XpmAttributes attrs
;
3368 Lisp_Object specified_file
, color_symbols
;
3371 xpm_XImage
* xpm_image
= NULL
, * xpm_mask
= NULL
;
3372 #endif /* HAVE_NTGUI */
3374 /* Configure the XPM lib. Use the visual of frame F. Allocate
3375 close colors. Return colors allocated. */
3376 memset (&attrs
, 0, sizeof attrs
);
3379 attrs
.visual
= FRAME_X_VISUAL (f
);
3380 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3381 attrs
.valuemask
|= XpmVisual
;
3382 attrs
.valuemask
|= XpmColormap
;
3383 #endif /* HAVE_NTGUI */
3385 #ifdef ALLOC_XPM_COLORS
3386 /* Allocate colors with our own functions which handle
3387 failing color allocation more gracefully. */
3388 attrs
.color_closure
= f
;
3389 attrs
.alloc_color
= xpm_alloc_color
;
3390 attrs
.free_colors
= xpm_free_colors
;
3391 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
3392 #else /* not ALLOC_XPM_COLORS */
3393 /* Let the XPM lib allocate colors. */
3394 attrs
.valuemask
|= XpmReturnAllocPixels
;
3395 #ifdef XpmAllocCloseColors
3396 attrs
.alloc_close_colors
= 1;
3397 attrs
.valuemask
|= XpmAllocCloseColors
;
3398 #else /* not XpmAllocCloseColors */
3399 attrs
.closeness
= 600;
3400 attrs
.valuemask
|= XpmCloseness
;
3401 #endif /* not XpmAllocCloseColors */
3402 #endif /* ALLOC_XPM_COLORS */
3404 /* If image specification contains symbolic color definitions, add
3405 these to `attrs'. */
3406 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
3407 if (CONSP (color_symbols
))
3410 XpmColorSymbol
*xpm_syms
;
3413 attrs
.valuemask
|= XpmColorSymbols
;
3415 /* Count number of symbols. */
3416 attrs
.numsymbols
= 0;
3417 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
3420 /* Allocate an XpmColorSymbol array. */
3421 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
3422 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
3423 memset (xpm_syms
, 0, size
);
3424 attrs
.colorsymbols
= xpm_syms
;
3426 /* Fill the color symbol array. */
3427 for (tail
= color_symbols
, i
= 0;
3429 ++i
, tail
= XCDR (tail
))
3434 if (!CONSP (XCAR (tail
)))
3436 xpm_syms
[i
].name
= "";
3437 xpm_syms
[i
].value
= "";
3440 name
= XCAR (XCAR (tail
));
3441 color
= XCDR (XCAR (tail
));
3444 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
3445 strcpy (xpm_syms
[i
].name
, SSDATA (name
));
3448 xpm_syms
[i
].name
= "";
3449 if (STRINGP (color
))
3451 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
3452 strcpy (xpm_syms
[i
].value
, SSDATA (color
));
3455 xpm_syms
[i
].value
= "";
3459 /* Create a pixmap for the image, either from a file, or from a
3460 string buffer containing data in the same format as an XPM file. */
3461 #ifdef ALLOC_XPM_COLORS
3462 xpm_init_color_cache (f
, &attrs
);
3465 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
3469 HDC frame_dc
= get_frame_dc (f
);
3470 hdc
= CreateCompatibleDC (frame_dc
);
3471 release_frame_dc (f
, frame_dc
);
3473 #endif /* HAVE_NTGUI */
3475 if (STRINGP (specified_file
))
3477 Lisp_Object file
= x_find_image_file (specified_file
);
3478 if (!STRINGP (file
))
3480 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
3481 #ifdef ALLOC_XPM_COLORS
3482 xpm_free_color_cache ();
3488 /* XpmReadFileToPixmap is not available in the Windows port of
3489 libxpm. But XpmReadFileToImage almost does what we want. */
3490 rc
= fn_XpmReadFileToImage (&hdc
, SDATA (file
),
3491 &xpm_image
, &xpm_mask
,
3494 rc
= XpmReadFileToPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3495 SSDATA (file
), &img
->pixmap
, &img
->mask
,
3497 #endif /* HAVE_NTGUI */
3501 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
3502 if (!STRINGP (buffer
))
3504 image_error ("Invalid image data `%s'", buffer
, Qnil
);
3505 #ifdef ALLOC_XPM_COLORS
3506 xpm_free_color_cache ();
3511 /* XpmCreatePixmapFromBuffer is not available in the Windows port
3512 of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
3513 rc
= fn_XpmCreateImageFromBuffer (&hdc
, SDATA (buffer
),
3514 &xpm_image
, &xpm_mask
,
3517 rc
= XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3519 &img
->pixmap
, &img
->mask
,
3521 #endif /* HAVE_NTGUI */
3524 if (rc
== XpmSuccess
)
3526 #if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS)
3527 img
->colors
= colors_in_color_table (&img
->ncolors
);
3528 #else /* not ALLOC_XPM_COLORS */
3532 /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
3533 plus some duplicate attributes. */
3534 if (xpm_image
&& xpm_image
->bitmap
)
3536 img
->pixmap
= xpm_image
->bitmap
;
3537 /* XImageFree in libXpm frees XImage struct without destroying
3538 the bitmap, which is what we want. */
3539 fn_XImageFree (xpm_image
);
3541 if (xpm_mask
&& xpm_mask
->bitmap
)
3543 /* The mask appears to be inverted compared with what we expect.
3544 TODO: invert our expectations. See other places where we
3545 have to invert bits because our idea of masks is backwards. */
3547 old_obj
= SelectObject (hdc
, xpm_mask
->bitmap
);
3549 PatBlt (hdc
, 0, 0, xpm_mask
->width
, xpm_mask
->height
, DSTINVERT
);
3550 SelectObject (hdc
, old_obj
);
3552 img
->mask
= xpm_mask
->bitmap
;
3553 fn_XImageFree (xpm_mask
);
3558 #endif /* HAVE_NTGUI */
3560 /* Remember allocated colors. */
3561 img
->ncolors
= attrs
.nalloc_pixels
;
3562 img
->colors
= (unsigned long *) xmalloc (img
->ncolors
3563 * sizeof *img
->colors
);
3564 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
3566 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
3567 #ifdef DEBUG_X_COLORS
3568 register_color (img
->colors
[i
]);
3571 #endif /* not ALLOC_XPM_COLORS */
3573 img
->width
= attrs
.width
;
3574 img
->height
= attrs
.height
;
3575 xassert (img
->width
> 0 && img
->height
> 0);
3577 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
3579 fn_XpmFreeAttributes (&attrs
);
3581 XpmFreeAttributes (&attrs
);
3582 #endif /* HAVE_NTGUI */
3588 #endif /* HAVE_NTGUI */
3593 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
3596 case XpmFileInvalid
:
3597 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
3601 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
3604 case XpmColorFailed
:
3605 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
3609 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
3614 #ifdef ALLOC_XPM_COLORS
3615 xpm_free_color_cache ();
3617 return rc
== XpmSuccess
;
3620 #endif /* HAVE_XPM */
3622 #if defined (HAVE_NS) && !defined (HAVE_XPM)
3624 /* XPM support functions for NS where libxpm is not available.
3625 Only XPM version 3 (without any extensions) is supported. */
3627 static int xpm_scan (const unsigned char **, const unsigned char *,
3628 const unsigned char **, int *);
3629 static Lisp_Object xpm_make_color_table_v
3630 (void (**) (Lisp_Object
, const unsigned char *, int, Lisp_Object
),
3631 Lisp_Object (**) (Lisp_Object
, const unsigned char *, int));
3632 static void xpm_put_color_table_v (Lisp_Object
, const unsigned char *,
3634 static Lisp_Object
xpm_get_color_table_v (Lisp_Object
,
3635 const unsigned char *, int);
3636 static Lisp_Object xpm_make_color_table_h
3637 (void (**) (Lisp_Object
, const unsigned char *, int, Lisp_Object
),
3638 Lisp_Object (**) (Lisp_Object
, const unsigned char *, int));
3639 static void xpm_put_color_table_h (Lisp_Object
, const unsigned char *,
3641 static Lisp_Object
xpm_get_color_table_h (Lisp_Object
,
3642 const unsigned char *, int);
3643 static int xpm_str_to_color_key (const char *);
3644 static int xpm_load_image (struct frame
*, struct image
*,
3645 const unsigned char *, const unsigned char *);
3647 /* Tokens returned from xpm_scan. */
3656 /* Scan an XPM data and return a character (< 256) or a token defined
3657 by enum xpm_token above. *S and END are the start (inclusive) and
3658 the end (exclusive) addresses of the data, respectively. Advance
3659 *S while scanning. If token is either XPM_TK_IDENT or
3660 XPM_TK_STRING, *BEG and *LEN are set to the start address and the
3661 length of the corresponding token, respectively. */
3664 xpm_scan (const unsigned char **s
,
3665 const unsigned char *end
,
3666 const unsigned char **beg
,
3673 /* Skip white-space. */
3674 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
3677 /* gnus-pointer.xpm uses '-' in its identifier.
3678 sb-dir-plus.xpm uses '+' in its identifier. */
3679 if (isalpha (c
) || c
== '_' || c
== '-' || c
== '+')
3683 && (c
= **s
, isalnum (c
) || c
== '_' || c
== '-' || c
== '+'))
3686 return XPM_TK_IDENT
;
3691 while (*s
< end
&& **s
!= '"')
3696 return XPM_TK_STRING
;
3700 if (*s
< end
&& **s
== '*')
3702 /* C-style comment. */
3706 while (*s
< end
&& *(*s
)++ != '*')
3709 while (*s
< end
&& **s
!= '/');
3723 /* Functions for color table lookup in XPM data. A key is a string
3724 specifying the color of each pixel in XPM data. A value is either
3725 an integer that specifies a pixel color, Qt that specifies
3726 transparency, or Qnil for the unspecified color. If the length of
3727 the key string is one, a vector is used as a table. Otherwise, a
3728 hash table is used. */
3731 xpm_make_color_table_v (void (**put_func
) (Lisp_Object
,
3732 const unsigned char *,
3735 Lisp_Object (**get_func
) (Lisp_Object
,
3736 const unsigned char *,
3739 *put_func
= xpm_put_color_table_v
;
3740 *get_func
= xpm_get_color_table_v
;
3741 return Fmake_vector (make_number (256), Qnil
);
3745 xpm_put_color_table_v (Lisp_Object color_table
,
3746 const unsigned char *chars_start
,
3750 XVECTOR (color_table
)->contents
[*chars_start
] = color
;
3754 xpm_get_color_table_v (Lisp_Object color_table
,
3755 const unsigned char *chars_start
,
3758 return XVECTOR (color_table
)->contents
[*chars_start
];
3762 xpm_make_color_table_h (void (**put_func
) (Lisp_Object
,
3763 const unsigned char *,
3766 Lisp_Object (**get_func
) (Lisp_Object
,
3767 const unsigned char *,
3770 *put_func
= xpm_put_color_table_h
;
3771 *get_func
= xpm_get_color_table_h
;
3772 return make_hash_table (Qequal
, make_number (DEFAULT_HASH_SIZE
),
3773 make_float (DEFAULT_REHASH_SIZE
),
3774 make_float (DEFAULT_REHASH_THRESHOLD
),
3779 xpm_put_color_table_h (Lisp_Object color_table
,
3780 const unsigned char *chars_start
,
3784 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
3786 Lisp_Object chars
= make_unibyte_string (chars_start
, chars_len
);
3788 hash_lookup (table
, chars
, &hash_code
);
3789 hash_put (table
, chars
, color
, hash_code
);
3793 xpm_get_color_table_h (Lisp_Object color_table
,
3794 const unsigned char *chars_start
,
3797 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
3798 int i
= hash_lookup (table
, make_unibyte_string (chars_start
, chars_len
),
3801 return i
>= 0 ? HASH_VALUE (table
, i
) : Qnil
;
3804 enum xpm_color_key
{
3812 static const char xpm_color_key_strings
[][4] = {"s", "m", "g4", "g", "c"};
3815 xpm_str_to_color_key (const char *s
)
3820 i
< sizeof xpm_color_key_strings
/ sizeof xpm_color_key_strings
[0];
3822 if (strcmp (xpm_color_key_strings
[i
], s
) == 0)
3828 xpm_load_image (struct frame
*f
,
3830 const unsigned char *contents
,
3831 const unsigned char *end
)
3833 const unsigned char *s
= contents
, *beg
, *str
;
3834 unsigned char buffer
[BUFSIZ
];
3835 int width
, height
, x
, y
;
3836 int num_colors
, chars_per_pixel
;
3838 void (*put_color_table
) (Lisp_Object
, const unsigned char *, int, Lisp_Object
);
3839 Lisp_Object (*get_color_table
) (Lisp_Object
, const unsigned char *, int);
3840 Lisp_Object frame
, color_symbols
, color_table
;
3841 int best_key
, have_mask
= 0;
3842 XImagePtr ximg
= NULL
, mask_img
= NULL
;
3845 LA1 = xpm_scan (&s, end, &beg, &len)
3847 #define expect(TOKEN) \
3848 if (LA1 != (TOKEN)) \
3853 #define expect_ident(IDENT) \
3854 if (LA1 == XPM_TK_IDENT \
3855 && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
3860 if (!(end
- s
>= 9 && memcmp (s
, "/* XPM */", 9) == 0))
3864 expect_ident ("static");
3865 expect_ident ("char");
3867 expect (XPM_TK_IDENT
);
3872 expect (XPM_TK_STRING
);
3875 memcpy (buffer
, beg
, len
);
3877 if (sscanf (buffer
, "%d %d %d %d", &width
, &height
,
3878 &num_colors
, &chars_per_pixel
) != 4
3879 || width
<= 0 || height
<= 0
3880 || num_colors
<= 0 || chars_per_pixel
<= 0)
3883 if (!check_image_size (f
, width
, height
))
3885 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
3891 XSETFRAME (frame
, f
);
3892 if (!NILP (Fxw_display_color_p (frame
)))
3893 best_key
= XPM_COLOR_KEY_C
;
3894 else if (!NILP (Fx_display_grayscale_p (frame
)))
3895 best_key
= (XFASTINT (Fx_display_planes (frame
)) > 2
3896 ? XPM_COLOR_KEY_G
: XPM_COLOR_KEY_G4
);
3898 best_key
= XPM_COLOR_KEY_M
;
3900 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
3901 if (chars_per_pixel
== 1)
3902 color_table
= xpm_make_color_table_v (&put_color_table
,
3905 color_table
= xpm_make_color_table_h (&put_color_table
,
3908 while (num_colors
-- > 0)
3910 char *color
, *max_color
;
3911 int key
, next_key
, max_key
= 0;
3912 Lisp_Object symbol_color
= Qnil
, color_val
;
3915 expect (XPM_TK_STRING
);
3916 if (len
<= chars_per_pixel
|| len
>= BUFSIZ
+ chars_per_pixel
)
3918 memcpy (buffer
, beg
+ chars_per_pixel
, len
- chars_per_pixel
);
3919 buffer
[len
- chars_per_pixel
] = '\0';
3921 str
= strtok (buffer
, " \t");
3924 key
= xpm_str_to_color_key (str
);
3929 color
= strtok (NULL
, " \t");
3933 while ((str
= strtok (NULL
, " \t")) != NULL
)
3935 next_key
= xpm_str_to_color_key (str
);
3938 color
[strlen (color
)] = ' ';
3941 if (key
== XPM_COLOR_KEY_S
)
3943 if (NILP (symbol_color
))
3944 symbol_color
= build_string (color
);
3946 else if (max_key
< key
&& key
<= best_key
)
3956 if (!NILP (color_symbols
) && !NILP (symbol_color
))
3958 Lisp_Object specified_color
= Fassoc (symbol_color
, color_symbols
);
3960 if (CONSP (specified_color
) && STRINGP (XCDR (specified_color
)))
3962 if (xstrcasecmp (SSDATA (XCDR (specified_color
)), "None") == 0)
3964 else if (x_defined_color (f
, SDATA (XCDR (specified_color
)),
3966 color_val
= make_number (cdef
.pixel
);
3969 if (NILP (color_val
) && max_key
> 0)
3971 if (xstrcasecmp (max_color
, "None") == 0)
3973 else if (x_defined_color (f
, max_color
, &cdef
, 0))
3974 color_val
= make_number (cdef
.pixel
);
3976 if (!NILP (color_val
))
3977 (*put_color_table
) (color_table
, beg
, chars_per_pixel
, color_val
);
3982 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
3983 &ximg
, &img
->pixmap
)
3985 || !x_create_x_image_and_pixmap (f
, width
, height
, 1,
3986 &mask_img
, &img
->mask
)
3990 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
3994 for (y
= 0; y
< height
; y
++)
3996 expect (XPM_TK_STRING
);
3998 if (len
< width
* chars_per_pixel
)
4000 for (x
= 0; x
< width
; x
++, str
+= chars_per_pixel
)
4002 Lisp_Object color_val
=
4003 (*get_color_table
) (color_table
, str
, chars_per_pixel
);
4005 XPutPixel (ximg
, x
, y
,
4006 (INTEGERP (color_val
) ? XINT (color_val
)
4007 : FRAME_FOREGROUND_PIXEL (f
)));
4009 XPutPixel (mask_img
, x
, y
,
4010 (!EQ (color_val
, Qt
) ? PIX_MASK_DRAW
4011 : (have_mask
= 1, PIX_MASK_RETAIN
)));
4013 if (EQ (color_val
, Qt
))
4014 ns_set_alpha (ximg
, x
, y
, 0);
4022 img
->height
= height
;
4024 /* Maybe fill in the background field while we have ximg handy. */
4025 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
4026 IMAGE_BACKGROUND (img
, f
, ximg
);
4028 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
4029 x_destroy_x_image (ximg
);
4033 /* Fill in the background_transparent field while we have the
4035 image_background_transparent (img
, f
, mask_img
);
4037 x_put_x_image (f
, mask_img
, img
->mask
, width
, height
);
4038 x_destroy_x_image (mask_img
);
4042 x_destroy_x_image (mask_img
);
4043 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4044 img
->mask
= NO_PIXMAP
;
4050 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
4052 x_destroy_x_image (ximg
);
4053 x_destroy_x_image (mask_img
);
4054 x_clear_image (f
, img
);
4063 xpm_load (struct frame
*f
,
4067 Lisp_Object file_name
;
4069 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4070 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
4071 if (STRINGP (file_name
))
4074 unsigned char *contents
;
4077 file
= x_find_image_file (file_name
);
4078 if (!STRINGP (file
))
4080 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
4084 contents
= slurp_file (SDATA (file
), &size
);
4085 if (contents
== NULL
)
4087 image_error ("Error loading XPM image `%s'", img
->spec
, Qnil
);
4091 success_p
= xpm_load_image (f
, img
, contents
, contents
+ size
);
4098 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
4099 if (!STRINGP (data
))
4101 image_error ("Invalid image data `%s'", data
, Qnil
);
4104 success_p
= xpm_load_image (f
, img
, SDATA (data
),
4105 SDATA (data
) + SBYTES (data
));
4111 #endif /* HAVE_NS && !HAVE_XPM */
4115 /***********************************************************************
4117 ***********************************************************************/
4119 #ifdef COLOR_TABLE_SUPPORT
4121 /* An entry in the color table mapping an RGB color to a pixel color. */
4126 unsigned long pixel
;
4128 /* Next in color table collision list. */
4129 struct ct_color
*next
;
4132 /* The bucket vector size to use. Must be prime. */
4136 /* Value is a hash of the RGB color given by R, G, and B. */
4138 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
4140 /* The color hash table. */
4142 struct ct_color
**ct_table
;
4144 /* Number of entries in the color table. */
4146 int ct_colors_allocated
;
4148 /* Initialize the color table. */
4151 init_color_table (void)
4153 int size
= CT_SIZE
* sizeof (*ct_table
);
4154 ct_table
= (struct ct_color
**) xmalloc (size
);
4155 memset (ct_table
, 0, size
);
4156 ct_colors_allocated
= 0;
4160 /* Free memory associated with the color table. */
4163 free_color_table (void)
4166 struct ct_color
*p
, *next
;
4168 for (i
= 0; i
< CT_SIZE
; ++i
)
4169 for (p
= ct_table
[i
]; p
; p
= next
)
4180 /* Value is a pixel color for RGB color R, G, B on frame F. If an
4181 entry for that color already is in the color table, return the
4182 pixel color of that entry. Otherwise, allocate a new color for R,
4183 G, B, and make an entry in the color table. */
4185 static unsigned long
4186 lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
)
4188 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
4189 int i
= hash
% CT_SIZE
;
4191 Display_Info
*dpyinfo
;
4193 /* Handle TrueColor visuals specially, which improves performance by
4194 two orders of magnitude. Freeing colors on TrueColor visuals is
4195 a nop, and pixel colors specify RGB values directly. See also
4196 the Xlib spec, chapter 3.1. */
4197 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
4198 if (dpyinfo
->red_bits
> 0)
4200 unsigned long pr
, pg
, pb
;
4202 /* Apply gamma-correction like normal color allocation does. */
4206 color
.red
= r
, color
.green
= g
, color
.blue
= b
;
4207 gamma_correct (f
, &color
);
4208 r
= color
.red
, g
= color
.green
, b
= color
.blue
;
4211 /* Scale down RGB values to the visual's bits per RGB, and shift
4212 them to the right position in the pixel color. Note that the
4213 original RGB values are 16-bit values, as usual in X. */
4214 pr
= (r
>> (16 - dpyinfo
->red_bits
)) << dpyinfo
->red_offset
;
4215 pg
= (g
>> (16 - dpyinfo
->green_bits
)) << dpyinfo
->green_offset
;
4216 pb
= (b
>> (16 - dpyinfo
->blue_bits
)) << dpyinfo
->blue_offset
;
4218 /* Assemble the pixel color. */
4219 return pr
| pg
| pb
;
4222 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4223 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
4229 #ifdef HAVE_X_WINDOWS
4238 cmap
= FRAME_X_COLORMAP (f
);
4239 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4242 ++ct_colors_allocated
;
4243 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4247 p
->pixel
= color
.pixel
;
4248 p
->next
= ct_table
[i
];
4252 return FRAME_FOREGROUND_PIXEL (f
);
4257 color
= PALETTERGB (r
, g
, b
);
4259 color
= RGB_TO_ULONG (r
, g
, b
);
4260 #endif /* HAVE_NTGUI */
4261 ++ct_colors_allocated
;
4262 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4267 p
->next
= ct_table
[i
];
4269 #endif /* HAVE_X_WINDOWS */
4277 /* Look up pixel color PIXEL which is used on frame F in the color
4278 table. If not already present, allocate it. Value is PIXEL. */
4280 static unsigned long
4281 lookup_pixel_color (struct frame
*f
, unsigned long pixel
)
4283 int i
= pixel
% CT_SIZE
;
4286 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4287 if (p
->pixel
== pixel
)
4296 #ifdef HAVE_X_WINDOWS
4297 cmap
= FRAME_X_COLORMAP (f
);
4298 color
.pixel
= pixel
;
4299 x_query_color (f
, &color
);
4300 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4303 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
4304 color
.pixel
= pixel
;
4305 XQueryColor (NULL
, cmap
, &color
);
4306 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4308 #endif /* HAVE_X_WINDOWS */
4312 ++ct_colors_allocated
;
4314 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4319 p
->next
= ct_table
[i
];
4323 return FRAME_FOREGROUND_PIXEL (f
);
4329 /* Value is a vector of all pixel colors contained in the color table,
4330 allocated via xmalloc. Set *N to the number of colors. */
4332 static unsigned long *
4333 colors_in_color_table (int *n
)
4337 unsigned long *colors
;
4339 if (ct_colors_allocated
== 0)
4346 colors
= (unsigned long *) xmalloc (ct_colors_allocated
4348 *n
= ct_colors_allocated
;
4350 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
4351 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4352 colors
[j
++] = p
->pixel
;
4358 #else /* COLOR_TABLE_SUPPORT */
4360 static unsigned long
4361 lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
)
4363 unsigned long pixel
;
4366 pixel
= PALETTERGB (r
>> 8, g
>> 8, b
>> 8);
4367 #endif /* HAVE_NTGUI */
4370 pixel
= RGB_TO_ULONG (r
>> 8, g
>> 8, b
>> 8);
4371 #endif /* HAVE_NS */
4376 init_color_table (void)
4379 #endif /* COLOR_TABLE_SUPPORT */
4382 /***********************************************************************
4384 ***********************************************************************/
4386 static XColor
*x_to_xcolors (struct frame
*, struct image
*, int);
4387 static void x_from_xcolors (struct frame
*, struct image
*, XColor
*);
4388 static void x_detect_edges (struct frame
*, struct image
*, int[9], int);
4391 static void XPutPixel (XImagePtr
, int, int, COLORREF
);
4392 #endif /* HAVE_NTGUI */
4394 /* Edge detection matrices for different edge-detection
4397 static int emboss_matrix
[9] = {
4399 2, -1, 0, /* y - 1 */
4401 0, 1, -2 /* y + 1 */
4404 static int laplace_matrix
[9] = {
4406 1, 0, 0, /* y - 1 */
4408 0, 0, -1 /* y + 1 */
4411 /* Value is the intensity of the color whose red/green/blue values
4414 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
4417 /* On frame F, return an array of XColor structures describing image
4418 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
4419 non-zero means also fill the red/green/blue members of the XColor
4420 structures. Value is a pointer to the array of XColors structures,
4421 allocated with xmalloc; it must be freed by the caller. */
4424 x_to_xcolors (struct frame
*f
, struct image
*img
, int rgb_p
)
4428 XImagePtr_or_DC ximg
;
4432 #endif /* HAVE_NTGUI */
4434 colors
= (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *colors
);
4437 /* Get the X image IMG->pixmap. */
4438 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
4439 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4441 /* Load the image into a memory device context. */
4442 hdc
= get_frame_dc (f
);
4443 ximg
= CreateCompatibleDC (hdc
);
4444 release_frame_dc (f
, hdc
);
4445 prev
= SelectObject (ximg
, img
->pixmap
);
4446 #endif /* HAVE_NTGUI */
4448 /* Fill the `pixel' members of the XColor array. I wished there
4449 were an easy and portable way to circumvent XGetPixel. */
4451 for (y
= 0; y
< img
->height
; ++y
)
4455 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
4456 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4457 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4459 x_query_colors (f
, row
, img
->width
);
4463 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4465 /* W32_TODO: palette support needed here? */
4466 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4469 p
->red
= RED16_FROM_ULONG (p
->pixel
);
4470 p
->green
= GREEN16_FROM_ULONG (p
->pixel
);
4471 p
->blue
= BLUE16_FROM_ULONG (p
->pixel
);
4474 #endif /* HAVE_X_WINDOWS */
4477 Destroy_Image (ximg
, prev
);
4484 /* Put a pixel of COLOR at position X, Y in XIMG. XIMG must have been
4485 created with CreateDIBSection, with the pointer to the bit values
4486 stored in ximg->data. */
4489 XPutPixel (XImagePtr ximg
, int x
, int y
, COLORREF color
)
4491 int width
= ximg
->info
.bmiHeader
.biWidth
;
4492 int height
= ximg
->info
.bmiHeader
.biHeight
;
4493 unsigned char * pixel
;
4495 /* True color images. */
4496 if (ximg
->info
.bmiHeader
.biBitCount
== 24)
4498 int rowbytes
= width
* 3;
4499 /* Ensure scanlines are aligned on 4 byte boundaries. */
4501 rowbytes
+= 4 - (rowbytes
% 4);
4503 pixel
= ximg
->data
+ y
* rowbytes
+ x
* 3;
4504 /* Windows bitmaps are in BGR order. */
4505 *pixel
= GetBValue (color
);
4506 *(pixel
+ 1) = GetGValue (color
);
4507 *(pixel
+ 2) = GetRValue (color
);
4509 /* Monochrome images. */
4510 else if (ximg
->info
.bmiHeader
.biBitCount
== 1)
4512 int rowbytes
= width
/ 8;
4513 /* Ensure scanlines are aligned on 4 byte boundaries. */
4515 rowbytes
+= 4 - (rowbytes
% 4);
4516 pixel
= ximg
->data
+ y
* rowbytes
+ x
/ 8;
4517 /* Filter out palette info. */
4518 if (color
& 0x00ffffff)
4519 *pixel
= *pixel
| (1 << x
% 8);
4521 *pixel
= *pixel
& ~(1 << x
% 8);
4524 image_error ("XPutPixel: palette image not supported", Qnil
, Qnil
);
4527 #endif /* HAVE_NTGUI */
4529 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
4530 RGB members are set. F is the frame on which this all happens.
4531 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
4534 x_from_xcolors (struct frame
*f
, struct image
*img
, XColor
*colors
)
4537 XImagePtr oimg
= NULL
;
4541 init_color_table ();
4543 x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
4546 for (y
= 0; y
< img
->height
; ++y
)
4547 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4549 unsigned long pixel
;
4550 pixel
= lookup_rgb_color (f
, p
->red
, p
->green
, p
->blue
);
4551 XPutPixel (oimg
, x
, y
, pixel
);
4555 x_clear_image_1 (f
, img
, 1, 0, 1);
4557 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
4558 x_destroy_x_image (oimg
);
4559 img
->pixmap
= pixmap
;
4560 #ifdef COLOR_TABLE_SUPPORT
4561 img
->colors
= colors_in_color_table (&img
->ncolors
);
4562 free_color_table ();
4563 #endif /* COLOR_TABLE_SUPPORT */
4567 /* On frame F, perform edge-detection on image IMG.
4569 MATRIX is a nine-element array specifying the transformation
4570 matrix. See emboss_matrix for an example.
4572 COLOR_ADJUST is a color adjustment added to each pixel of the
4576 x_detect_edges (struct frame
*f
, struct image
*img
, int *matrix
, int color_adjust
)
4578 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4582 for (i
= sum
= 0; i
< 9; ++i
)
4583 sum
+= eabs (matrix
[i
]);
4585 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
4587 new = (XColor
*) xmalloc (img
->width
* img
->height
* sizeof *new);
4589 for (y
= 0; y
< img
->height
; ++y
)
4591 p
= COLOR (new, 0, y
);
4592 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4593 p
= COLOR (new, img
->width
- 1, y
);
4594 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4597 for (x
= 1; x
< img
->width
- 1; ++x
)
4599 p
= COLOR (new, x
, 0);
4600 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4601 p
= COLOR (new, x
, img
->height
- 1);
4602 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4605 for (y
= 1; y
< img
->height
- 1; ++y
)
4607 p
= COLOR (new, 1, y
);
4609 for (x
= 1; x
< img
->width
- 1; ++x
, ++p
)
4611 int r
, g
, b
, y1
, x1
;
4614 for (y1
= y
- 1; y1
< y
+ 2; ++y1
)
4615 for (x1
= x
- 1; x1
< x
+ 2; ++x1
, ++i
)
4618 XColor
*t
= COLOR (colors
, x1
, y1
);
4619 r
+= matrix
[i
] * t
->red
;
4620 g
+= matrix
[i
] * t
->green
;
4621 b
+= matrix
[i
] * t
->blue
;
4624 r
= (r
/ sum
+ color_adjust
) & 0xffff;
4625 g
= (g
/ sum
+ color_adjust
) & 0xffff;
4626 b
= (b
/ sum
+ color_adjust
) & 0xffff;
4627 p
->red
= p
->green
= p
->blue
= COLOR_INTENSITY (r
, g
, b
);
4632 x_from_xcolors (f
, img
, new);
4638 /* Perform the pre-defined `emboss' edge-detection on image IMG
4642 x_emboss (struct frame
*f
, struct image
*img
)
4644 x_detect_edges (f
, img
, emboss_matrix
, 0xffff / 2);
4648 /* Transform image IMG which is used on frame F with a Laplace
4649 edge-detection algorithm. The result is an image that can be used
4650 to draw disabled buttons, for example. */
4653 x_laplace (struct frame
*f
, struct image
*img
)
4655 x_detect_edges (f
, img
, laplace_matrix
, 45000);
4659 /* Perform edge-detection on image IMG on frame F, with specified
4660 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
4662 MATRIX must be either
4664 - a list of at least 9 numbers in row-major form
4665 - a vector of at least 9 numbers
4667 COLOR_ADJUST nil means use a default; otherwise it must be a
4671 x_edge_detection (struct frame
*f
, struct image
*img
, Lisp_Object matrix
,
4672 Lisp_Object color_adjust
)
4680 i
< 9 && CONSP (matrix
) && NUMBERP (XCAR (matrix
));
4681 ++i
, matrix
= XCDR (matrix
))
4682 trans
[i
] = XFLOATINT (XCAR (matrix
));
4684 else if (VECTORP (matrix
) && ASIZE (matrix
) >= 9)
4686 for (i
= 0; i
< 9 && NUMBERP (AREF (matrix
, i
)); ++i
)
4687 trans
[i
] = XFLOATINT (AREF (matrix
, i
));
4690 if (NILP (color_adjust
))
4691 color_adjust
= make_number (0xffff / 2);
4693 if (i
== 9 && NUMBERP (color_adjust
))
4694 x_detect_edges (f
, img
, trans
, (int) XFLOATINT (color_adjust
));
4698 /* Transform image IMG on frame F so that it looks disabled. */
4701 x_disable_image (struct frame
*f
, struct image
*img
)
4703 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
4705 int n_planes
= dpyinfo
->n_planes
* dpyinfo
->n_cbits
;
4707 int n_planes
= dpyinfo
->n_planes
;
4708 #endif /* HAVE_NTGUI */
4712 /* Color (or grayscale). Convert to gray, and equalize. Just
4713 drawing such images with a stipple can look very odd, so
4714 we're using this method instead. */
4715 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4717 const int h
= 15000;
4718 const int l
= 30000;
4720 for (p
= colors
, end
= colors
+ img
->width
* img
->height
;
4724 int i
= COLOR_INTENSITY (p
->red
, p
->green
, p
->blue
);
4725 int i2
= (0xffff - h
- l
) * i
/ 0xffff + l
;
4726 p
->red
= p
->green
= p
->blue
= i2
;
4729 x_from_xcolors (f
, img
, colors
);
4732 /* Draw a cross over the disabled image, if we must or if we
4734 if (n_planes
< 2 || cross_disabled_images
)
4737 Display
*dpy
= FRAME_X_DISPLAY (f
);
4740 #ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
4742 #define MaskForeground(f) WHITE_PIX_DEFAULT (f)
4744 gc
= XCreateGC (dpy
, img
->pixmap
, 0, NULL
);
4745 XSetForeground (dpy
, gc
, BLACK_PIX_DEFAULT (f
));
4746 XDrawLine (dpy
, img
->pixmap
, gc
, 0, 0,
4747 img
->width
- 1, img
->height
- 1);
4748 XDrawLine (dpy
, img
->pixmap
, gc
, 0, img
->height
- 1,
4754 gc
= XCreateGC (dpy
, img
->mask
, 0, NULL
);
4755 XSetForeground (dpy
, gc
, MaskForeground (f
));
4756 XDrawLine (dpy
, img
->mask
, gc
, 0, 0,
4757 img
->width
- 1, img
->height
- 1);
4758 XDrawLine (dpy
, img
->mask
, gc
, 0, img
->height
- 1,
4762 #endif /* !HAVE_NS */
4767 hdc
= get_frame_dc (f
);
4768 bmpdc
= CreateCompatibleDC (hdc
);
4769 release_frame_dc (f
, hdc
);
4771 prev
= SelectObject (bmpdc
, img
->pixmap
);
4773 SetTextColor (bmpdc
, BLACK_PIX_DEFAULT (f
));
4774 MoveToEx (bmpdc
, 0, 0, NULL
);
4775 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
4776 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
4777 LineTo (bmpdc
, img
->width
- 1, 0);
4781 SelectObject (bmpdc
, img
->mask
);
4782 SetTextColor (bmpdc
, WHITE_PIX_DEFAULT (f
));
4783 MoveToEx (bmpdc
, 0, 0, NULL
);
4784 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
4785 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
4786 LineTo (bmpdc
, img
->width
- 1, 0);
4788 SelectObject (bmpdc
, prev
);
4790 #endif /* HAVE_NTGUI */
4795 /* Build a mask for image IMG which is used on frame F. FILE is the
4796 name of an image file, for error messages. HOW determines how to
4797 determine the background color of IMG. If it is a list '(R G B)',
4798 with R, G, and B being integers >= 0, take that as the color of the
4799 background. Otherwise, determine the background color of IMG
4800 heuristically. Value is non-zero if successful. */
4803 x_build_heuristic_mask (struct frame
*f
, struct image
*img
, Lisp_Object how
)
4805 XImagePtr_or_DC ximg
;
4813 #endif /* HAVE_NTGUI */
4814 int x
, y
, rc
, use_img_background
;
4815 unsigned long bg
= 0;
4819 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4820 img
->mask
= NO_PIXMAP
;
4821 img
->background_transparent_valid
= 0;
4826 /* Create an image and pixmap serving as mask. */
4827 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
4828 &mask_img
, &img
->mask
);
4831 #endif /* !HAVE_NS */
4833 /* Get the X image of IMG->pixmap. */
4834 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
, 0, 0,
4835 img
->width
, img
->height
,
4838 /* Create the bit array serving as mask. */
4839 row_width
= (img
->width
+ 7) / 8;
4840 mask_img
= xmalloc (row_width
* img
->height
);
4841 memset (mask_img
, 0, row_width
* img
->height
);
4843 /* Create a memory device context for IMG->pixmap. */
4844 frame_dc
= get_frame_dc (f
);
4845 ximg
= CreateCompatibleDC (frame_dc
);
4846 release_frame_dc (f
, frame_dc
);
4847 prev
= SelectObject (ximg
, img
->pixmap
);
4848 #endif /* HAVE_NTGUI */
4850 /* Determine the background color of ximg. If HOW is `(R G B)'
4851 take that as color. Otherwise, use the image's background color. */
4852 use_img_background
= 1;
4858 for (i
= 0; i
< 3 && CONSP (how
) && NATNUMP (XCAR (how
)); ++i
)
4860 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
4864 if (i
== 3 && NILP (how
))
4866 char color_name
[30];
4867 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
4870 0x00ffffff & /* Filter out palette info. */
4871 #endif /* HAVE_NTGUI */
4872 x_alloc_image_color (f
, img
, build_string (color_name
), 0));
4873 use_img_background
= 0;
4877 if (use_img_background
)
4878 bg
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
4880 /* Set all bits in mask_img to 1 whose color in ximg is different
4881 from the background color bg. */
4883 for (y
= 0; y
< img
->height
; ++y
)
4884 for (x
= 0; x
< img
->width
; ++x
)
4886 XPutPixel (mask_img
, x
, y
, (XGetPixel (ximg
, x
, y
) != bg
4887 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
));
4889 if (XGetPixel (ximg
, x
, y
) == bg
)
4890 ns_set_alpha (ximg
, x
, y
, 0);
4891 #endif /* HAVE_NS */
4893 /* Fill in the background_transparent field while we have the mask handy. */
4894 image_background_transparent (img
, f
, mask_img
);
4896 /* Put mask_img into img->mask. */
4897 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
4898 x_destroy_x_image (mask_img
);
4899 #endif /* !HAVE_NS */
4901 for (y
= 0; y
< img
->height
; ++y
)
4902 for (x
= 0; x
< img
->width
; ++x
)
4904 COLORREF p
= GetPixel (ximg
, x
, y
);
4906 mask_img
[y
* row_width
+ x
/ 8] |= 1 << (x
% 8);
4909 /* Create the mask image. */
4910 img
->mask
= w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
,
4912 /* Fill in the background_transparent field while we have the mask handy. */
4913 SelectObject (ximg
, img
->mask
);
4914 image_background_transparent (img
, f
, ximg
);
4916 /* Was: x_destroy_x_image ((XImagePtr )mask_img); which seems bogus ++kfs */
4918 #endif /* HAVE_NTGUI */
4920 Destroy_Image (ximg
, prev
);
4926 /***********************************************************************
4927 PBM (mono, gray, color)
4928 ***********************************************************************/
4930 static int pbm_image_p (Lisp_Object object
);
4931 static int pbm_load (struct frame
*f
, struct image
*img
);
4932 static int pbm_scan_number (unsigned char **, unsigned char *);
4934 /* The symbol `pbm' identifying images of this type. */
4938 /* Indices of image specification fields in gs_format, below. */
4940 enum pbm_keyword_index
4956 /* Vector of image_keyword structures describing the format
4957 of valid user-defined image specifications. */
4959 static const struct image_keyword pbm_format
[PBM_LAST
] =
4961 {":type", IMAGE_SYMBOL_VALUE
, 1},
4962 {":file", IMAGE_STRING_VALUE
, 0},
4963 {":data", IMAGE_STRING_VALUE
, 0},
4964 {":ascent", IMAGE_ASCENT_VALUE
, 0},
4965 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
4966 {":relief", IMAGE_INTEGER_VALUE
, 0},
4967 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4968 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4969 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4970 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
4971 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
4974 /* Structure describing the image type `pbm'. */
4976 static struct image_type pbm_type
=
4986 /* Return non-zero if OBJECT is a valid PBM image specification. */
4989 pbm_image_p (Lisp_Object object
)
4991 struct image_keyword fmt
[PBM_LAST
];
4993 memcpy (fmt
, pbm_format
, sizeof fmt
);
4995 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
))
4998 /* Must specify either :data or :file. */
4999 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
5003 /* Scan a decimal number from *S and return it. Advance *S while
5004 reading the number. END is the end of the string. Value is -1 at
5008 pbm_scan_number (unsigned char **s
, unsigned char *end
)
5010 int c
= 0, val
= -1;
5014 /* Skip white-space. */
5015 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
5020 /* Skip comment to end of line. */
5021 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
5024 else if (isdigit (c
))
5026 /* Read decimal number. */
5028 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
5029 val
= 10 * val
+ c
- '0';
5041 #if 0 /* Unused. ++kfs */
5043 /* Read FILE into memory. Value is a pointer to a buffer allocated
5044 with xmalloc holding FILE's contents. Value is null if an error
5045 occurred. *SIZE is set to the size of the file. */
5048 pbm_read_file (file
, size
)
5056 if (stat (SDATA (file
), &st
) == 0
5057 && (fp
= fopen (SDATA (file
), "rb")) != NULL
5058 && (buf
= (char *) xmalloc (st
.st_size
),
5059 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
5078 #endif /* HAVE_NTGUI */
5080 /* Load PBM image IMG for use on frame F. */
5083 pbm_load (struct frame
*f
, struct image
*img
)
5086 int width
, height
, max_color_idx
= 0;
5088 Lisp_Object file
, specified_file
;
5089 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
5090 unsigned char *contents
= NULL
;
5091 unsigned char *end
, *p
;
5094 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5096 if (STRINGP (specified_file
))
5098 file
= x_find_image_file (specified_file
);
5099 if (!STRINGP (file
))
5101 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5105 contents
= slurp_file (SSDATA (file
), &size
);
5106 if (contents
== NULL
)
5108 image_error ("Error reading `%s'", file
, Qnil
);
5113 end
= contents
+ size
;
5118 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5119 if (!STRINGP (data
))
5121 image_error ("Invalid image data `%s'", data
, Qnil
);
5125 end
= p
+ SBYTES (data
);
5128 /* Check magic number. */
5129 if (end
- p
< 2 || *p
++ != 'P')
5131 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5140 raw_p
= 0, type
= PBM_MONO
;
5144 raw_p
= 0, type
= PBM_GRAY
;
5148 raw_p
= 0, type
= PBM_COLOR
;
5152 raw_p
= 1, type
= PBM_MONO
;
5156 raw_p
= 1, type
= PBM_GRAY
;
5160 raw_p
= 1, type
= PBM_COLOR
;
5164 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5168 /* Read width, height, maximum color-component. Characters
5169 starting with `#' up to the end of a line are ignored. */
5170 width
= pbm_scan_number (&p
, end
);
5171 height
= pbm_scan_number (&p
, end
);
5173 if (type
!= PBM_MONO
)
5175 max_color_idx
= pbm_scan_number (&p
, end
);
5176 if (max_color_idx
> 65535 || max_color_idx
< 0)
5178 image_error ("Unsupported maximum PBM color value", Qnil
, Qnil
);
5183 if (!check_image_size (f
, width
, height
))
5185 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
5189 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
5190 &ximg
, &img
->pixmap
))
5193 /* Initialize the color hash table. */
5194 init_color_table ();
5196 if (type
== PBM_MONO
)
5199 struct image_keyword fmt
[PBM_LAST
];
5200 unsigned long fg
= FRAME_FOREGROUND_PIXEL (f
);
5201 unsigned long bg
= FRAME_BACKGROUND_PIXEL (f
);
5203 /* Parse the image specification. */
5204 memcpy (fmt
, pbm_format
, sizeof fmt
);
5205 parse_image_spec (img
->spec
, fmt
, PBM_LAST
, Qpbm
);
5207 /* Get foreground and background colors, maybe allocate colors. */
5208 if (fmt
[PBM_FOREGROUND
].count
5209 && STRINGP (fmt
[PBM_FOREGROUND
].value
))
5210 fg
= x_alloc_image_color (f
, img
, fmt
[PBM_FOREGROUND
].value
, fg
);
5211 if (fmt
[PBM_BACKGROUND
].count
5212 && STRINGP (fmt
[PBM_BACKGROUND
].value
))
5214 bg
= x_alloc_image_color (f
, img
, fmt
[PBM_BACKGROUND
].value
, bg
);
5215 img
->background
= bg
;
5216 img
->background_valid
= 1;
5219 for (y
= 0; y
< height
; ++y
)
5220 for (x
= 0; x
< width
; ++x
)
5228 x_destroy_x_image (ximg
);
5229 x_clear_image (f
, img
);
5230 image_error ("Invalid image size in image `%s'",
5240 g
= pbm_scan_number (&p
, end
);
5242 XPutPixel (ximg
, x
, y
, g
? fg
: bg
);
5247 int expected_size
= height
* width
;
5248 if (max_color_idx
> 255)
5250 if (type
== PBM_COLOR
)
5253 if (raw_p
&& p
+ expected_size
> end
)
5255 x_destroy_x_image (ximg
);
5256 x_clear_image (f
, img
);
5257 image_error ("Invalid image size in image `%s'",
5262 for (y
= 0; y
< height
; ++y
)
5263 for (x
= 0; x
< width
; ++x
)
5267 if (type
== PBM_GRAY
&& raw_p
)
5270 if (max_color_idx
> 255)
5271 r
= g
= b
= r
* 256 + *p
++;
5273 else if (type
== PBM_GRAY
)
5274 r
= g
= b
= pbm_scan_number (&p
, end
);
5278 if (max_color_idx
> 255)
5281 if (max_color_idx
> 255)
5284 if (max_color_idx
> 255)
5289 r
= pbm_scan_number (&p
, end
);
5290 g
= pbm_scan_number (&p
, end
);
5291 b
= pbm_scan_number (&p
, end
);
5294 if (r
< 0 || g
< 0 || b
< 0)
5296 x_destroy_x_image (ximg
);
5297 image_error ("Invalid pixel value in image `%s'",
5302 /* RGB values are now in the range 0..max_color_idx.
5303 Scale this to the range 0..0xffff supported by X. */
5304 r
= (double) r
* 65535 / max_color_idx
;
5305 g
= (double) g
* 65535 / max_color_idx
;
5306 b
= (double) b
* 65535 / max_color_idx
;
5307 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
5311 #ifdef COLOR_TABLE_SUPPORT
5312 /* Store in IMG->colors the colors allocated for the image, and
5313 free the color table. */
5314 img
->colors
= colors_in_color_table (&img
->ncolors
);
5315 free_color_table ();
5316 #endif /* COLOR_TABLE_SUPPORT */
5319 img
->height
= height
;
5321 /* Maybe fill in the background field while we have ximg handy. */
5323 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
5324 /* Casting avoids a GCC warning. */
5325 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
5327 /* Put the image into a pixmap. */
5328 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
5329 x_destroy_x_image (ximg
);
5331 /* X and W32 versions did it here, MAC version above. ++kfs
5333 img->height = height; */
5340 /***********************************************************************
5342 ***********************************************************************/
5344 #if defined (HAVE_PNG) || defined (HAVE_NS)
5346 /* Function prototypes. */
5348 static int png_image_p (Lisp_Object object
);
5349 static int png_load (struct frame
*f
, struct image
*img
);
5351 /* The symbol `png' identifying images of this type. */
5355 /* Indices of image specification fields in png_format, below. */
5357 enum png_keyword_index
5372 /* Vector of image_keyword structures describing the format
5373 of valid user-defined image specifications. */
5375 static const struct image_keyword png_format
[PNG_LAST
] =
5377 {":type", IMAGE_SYMBOL_VALUE
, 1},
5378 {":data", IMAGE_STRING_VALUE
, 0},
5379 {":file", IMAGE_STRING_VALUE
, 0},
5380 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5381 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5382 {":relief", IMAGE_INTEGER_VALUE
, 0},
5383 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5384 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5385 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5386 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
5389 /* Structure describing the image type `png'. */
5391 static struct image_type png_type
=
5400 /* Return non-zero if OBJECT is a valid PNG image specification. */
5403 png_image_p (Lisp_Object object
)
5405 struct image_keyword fmt
[PNG_LAST
];
5406 memcpy (fmt
, png_format
, sizeof fmt
);
5408 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
5411 /* Must specify either the :data or :file keyword. */
5412 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
5415 #endif /* HAVE_PNG || HAVE_NS */
5421 /* PNG library details. */
5423 DEF_IMGLIB_FN (png_voidp
, png_get_io_ptr
, (png_structp
));
5424 DEF_IMGLIB_FN (int, png_sig_cmp
, (png_bytep
, png_size_t
, png_size_t
));
5425 DEF_IMGLIB_FN (png_structp
, png_create_read_struct
, (png_const_charp
, png_voidp
,
5426 png_error_ptr
, png_error_ptr
));
5427 DEF_IMGLIB_FN (png_infop
, png_create_info_struct
, (png_structp
));
5428 DEF_IMGLIB_FN (void, png_destroy_read_struct
, (png_structpp
, png_infopp
, png_infopp
));
5429 DEF_IMGLIB_FN (void, png_set_read_fn
, (png_structp
, png_voidp
, png_rw_ptr
));
5430 DEF_IMGLIB_FN (void, png_set_sig_bytes
, (png_structp
, int));
5431 DEF_IMGLIB_FN (void, png_read_info
, (png_structp
, png_infop
));
5432 DEF_IMGLIB_FN (png_uint_32
, png_get_IHDR
, (png_structp
, png_infop
,
5433 png_uint_32
*, png_uint_32
*,
5434 int *, int *, int *, int *, int *));
5435 DEF_IMGLIB_FN (png_uint_32
, png_get_valid
, (png_structp
, png_infop
, png_uint_32
));
5436 DEF_IMGLIB_FN (void, png_set_strip_16
, (png_structp
));
5437 DEF_IMGLIB_FN (void, png_set_expand
, (png_structp
));
5438 DEF_IMGLIB_FN (void, png_set_gray_to_rgb
, (png_structp
));
5439 DEF_IMGLIB_FN (void, png_set_background
, (png_structp
, png_color_16p
,
5441 DEF_IMGLIB_FN (png_uint_32
, png_get_bKGD
, (png_structp
, png_infop
, png_color_16p
*));
5442 DEF_IMGLIB_FN (void, png_read_update_info
, (png_structp
, png_infop
));
5443 DEF_IMGLIB_FN (png_byte
, png_get_channels
, (png_structp
, png_infop
));
5444 DEF_IMGLIB_FN (png_size_t
, png_get_rowbytes
, (png_structp
, png_infop
));
5445 DEF_IMGLIB_FN (void, png_read_image
, (png_structp
, png_bytepp
));
5446 DEF_IMGLIB_FN (void, png_read_end
, (png_structp
, png_infop
));
5447 DEF_IMGLIB_FN (void, png_error
, (png_structp
, png_const_charp
));
5449 #if (PNG_LIBPNG_VER >= 10500)
5450 DEF_IMGLIB_FN (void, png_longjmp
, (png_structp
, int));
5451 DEF_IMGLIB_FN (jmp_buf *, png_set_longjmp_fn
, (png_structp
, png_longjmp_ptr
, size_t));
5452 #endif /* libpng version >= 1.5 */
5455 init_png_functions (Lisp_Object libraries
)
5459 /* Try loading libpng under probable names. */
5460 if (!(library
= w32_delayed_load (libraries
, Qpng
)))
5463 LOAD_IMGLIB_FN (library
, png_get_io_ptr
);
5464 LOAD_IMGLIB_FN (library
, png_sig_cmp
);
5465 LOAD_IMGLIB_FN (library
, png_create_read_struct
);
5466 LOAD_IMGLIB_FN (library
, png_create_info_struct
);
5467 LOAD_IMGLIB_FN (library
, png_destroy_read_struct
);
5468 LOAD_IMGLIB_FN (library
, png_set_read_fn
);
5469 LOAD_IMGLIB_FN (library
, png_set_sig_bytes
);
5470 LOAD_IMGLIB_FN (library
, png_read_info
);
5471 LOAD_IMGLIB_FN (library
, png_get_IHDR
);
5472 LOAD_IMGLIB_FN (library
, png_get_valid
);
5473 LOAD_IMGLIB_FN (library
, png_set_strip_16
);
5474 LOAD_IMGLIB_FN (library
, png_set_expand
);
5475 LOAD_IMGLIB_FN (library
, png_set_gray_to_rgb
);
5476 LOAD_IMGLIB_FN (library
, png_set_background
);
5477 LOAD_IMGLIB_FN (library
, png_get_bKGD
);
5478 LOAD_IMGLIB_FN (library
, png_read_update_info
);
5479 LOAD_IMGLIB_FN (library
, png_get_channels
);
5480 LOAD_IMGLIB_FN (library
, png_get_rowbytes
);
5481 LOAD_IMGLIB_FN (library
, png_read_image
);
5482 LOAD_IMGLIB_FN (library
, png_read_end
);
5483 LOAD_IMGLIB_FN (library
, png_error
);
5485 #if (PNG_LIBPNG_VER >= 10500)
5486 LOAD_IMGLIB_FN (library
, png_longjmp
);
5487 LOAD_IMGLIB_FN (library
, png_set_longjmp_fn
);
5488 #endif /* libpng version >= 1.5 */
5494 #define fn_png_get_io_ptr png_get_io_ptr
5495 #define fn_png_sig_cmp png_sig_cmp
5496 #define fn_png_create_read_struct png_create_read_struct
5497 #define fn_png_create_info_struct png_create_info_struct
5498 #define fn_png_destroy_read_struct png_destroy_read_struct
5499 #define fn_png_set_read_fn png_set_read_fn
5500 #define fn_png_set_sig_bytes png_set_sig_bytes
5501 #define fn_png_read_info png_read_info
5502 #define fn_png_get_IHDR png_get_IHDR
5503 #define fn_png_get_valid png_get_valid
5504 #define fn_png_set_strip_16 png_set_strip_16
5505 #define fn_png_set_expand png_set_expand
5506 #define fn_png_set_gray_to_rgb png_set_gray_to_rgb
5507 #define fn_png_set_background png_set_background
5508 #define fn_png_get_bKGD png_get_bKGD
5509 #define fn_png_read_update_info png_read_update_info
5510 #define fn_png_get_channels png_get_channels
5511 #define fn_png_get_rowbytes png_get_rowbytes
5512 #define fn_png_read_image png_read_image
5513 #define fn_png_read_end png_read_end
5514 #define fn_png_error png_error
5516 #if (PNG_LIBPNG_VER >= 10500)
5517 #define fn_png_longjmp png_longjmp
5518 #define fn_png_set_longjmp_fn png_set_longjmp_fn
5519 #endif /* libpng version >= 1.5 */
5521 #endif /* HAVE_NTGUI */
5524 #if (PNG_LIBPNG_VER < 10500)
5525 #define PNG_LONGJMP(ptr) (longjmp ((ptr)->jmpbuf, 1))
5526 #define PNG_JMPBUF(ptr) ((ptr)->jmpbuf)
5528 /* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908) */
5529 #define PNG_LONGJMP(ptr) (fn_png_longjmp ((ptr), 1))
5530 #define PNG_JMPBUF(ptr) \
5531 (*fn_png_set_longjmp_fn((ptr), longjmp, sizeof (jmp_buf)))
5534 /* Error and warning handlers installed when the PNG library
5538 my_png_error (png_struct
*png_ptr
, const char *msg
)
5540 xassert (png_ptr
!= NULL
);
5541 /* Avoid compiler warning about deprecated direct access to
5542 png_ptr's fields in libpng versions 1.4.x. */
5543 image_error ("PNG error: %s", build_string (msg
), Qnil
);
5544 PNG_LONGJMP (png_ptr
);
5549 my_png_warning (png_struct
*png_ptr
, const char *msg
)
5551 xassert (png_ptr
!= NULL
);
5552 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
5555 /* Memory source for PNG decoding. */
5557 struct png_memory_storage
5559 unsigned char *bytes
; /* The data */
5560 size_t len
; /* How big is it? */
5561 int index
; /* Where are we? */
5565 /* Function set as reader function when reading PNG image from memory.
5566 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5567 bytes from the input to DATA. */
5570 png_read_from_memory (png_structp png_ptr
, png_bytep data
, png_size_t length
)
5572 struct png_memory_storage
*tbr
5573 = (struct png_memory_storage
*) fn_png_get_io_ptr (png_ptr
);
5575 if (length
> tbr
->len
- tbr
->index
)
5576 fn_png_error (png_ptr
, "Read error");
5578 memcpy (data
, tbr
->bytes
+ tbr
->index
, length
);
5579 tbr
->index
= tbr
->index
+ length
;
5583 /* Function set as reader function when reading PNG image from a file.
5584 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5585 bytes from the input to DATA. */
5588 png_read_from_file (png_structp png_ptr
, png_bytep data
, png_size_t length
)
5590 FILE *fp
= (FILE *) fn_png_get_io_ptr (png_ptr
);
5592 if (fread (data
, 1, length
, fp
) < length
)
5593 fn_png_error (png_ptr
, "Read error");
5597 /* Load PNG image IMG for use on frame F. Value is non-zero if
5601 png_load (struct frame
*f
, struct image
*img
)
5603 Lisp_Object file
, specified_file
;
5604 Lisp_Object specified_data
;
5606 XImagePtr ximg
, mask_img
= NULL
;
5607 png_struct
*png_ptr
= NULL
;
5608 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
5609 FILE *volatile fp
= NULL
;
5611 png_byte
* volatile pixels
= NULL
;
5612 png_byte
** volatile rows
= NULL
;
5613 png_uint_32 width
, height
;
5614 int bit_depth
, color_type
, interlace_type
;
5616 png_uint_32 row_bytes
;
5618 struct png_memory_storage tbr
; /* Data to be read */
5620 /* Find out what file to load. */
5621 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5622 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5624 if (NILP (specified_data
))
5626 file
= x_find_image_file (specified_file
);
5627 if (!STRINGP (file
))
5629 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5633 /* Open the image file. */
5634 fp
= fopen (SSDATA (file
), "rb");
5637 image_error ("Cannot open image file `%s'", file
, Qnil
);
5641 /* Check PNG signature. */
5642 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
5643 || fn_png_sig_cmp (sig
, 0, sizeof sig
))
5645 image_error ("Not a PNG file: `%s'", file
, Qnil
);
5652 if (!STRINGP (specified_data
))
5654 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
5658 /* Read from memory. */
5659 tbr
.bytes
= SDATA (specified_data
);
5660 tbr
.len
= SBYTES (specified_data
);
5663 /* Check PNG signature. */
5664 if (tbr
.len
< sizeof sig
5665 || fn_png_sig_cmp (tbr
.bytes
, 0, sizeof sig
))
5667 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
5671 /* Need to skip past the signature. */
5672 tbr
.bytes
+= sizeof (sig
);
5675 /* Initialize read and info structs for PNG lib. */
5676 png_ptr
= fn_png_create_read_struct (PNG_LIBPNG_VER_STRING
,
5681 if (fp
) fclose (fp
);
5685 info_ptr
= fn_png_create_info_struct (png_ptr
);
5688 fn_png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
5689 if (fp
) fclose (fp
);
5693 end_info
= fn_png_create_info_struct (png_ptr
);
5696 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
5697 if (fp
) fclose (fp
);
5701 /* Set error jump-back. We come back here when the PNG library
5702 detects an error. */
5703 if (setjmp (PNG_JMPBUF (png_ptr
)))
5707 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
5710 if (fp
) fclose (fp
);
5714 /* Read image info. */
5715 if (!NILP (specified_data
))
5716 fn_png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
5718 fn_png_set_read_fn (png_ptr
, (void *) fp
, png_read_from_file
);
5720 fn_png_set_sig_bytes (png_ptr
, sizeof sig
);
5721 fn_png_read_info (png_ptr
, info_ptr
);
5722 fn_png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
5723 &interlace_type
, NULL
, NULL
);
5725 if (!check_image_size (f
, width
, height
))
5727 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
5730 /* If image contains simply transparency data, we prefer to
5731 construct a clipping mask. */
5732 if (fn_png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
5737 /* This function is easier to write if we only have to handle
5738 one data format: RGB or RGBA with 8 bits per channel. Let's
5739 transform other formats into that format. */
5741 /* Strip more than 8 bits per channel. */
5742 if (bit_depth
== 16)
5743 fn_png_set_strip_16 (png_ptr
);
5745 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
5747 fn_png_set_expand (png_ptr
);
5749 /* Convert grayscale images to RGB. */
5750 if (color_type
== PNG_COLOR_TYPE_GRAY
5751 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
5752 fn_png_set_gray_to_rgb (png_ptr
);
5754 /* Handle alpha channel by combining the image with a background
5755 color. Do this only if a real alpha channel is supplied. For
5756 simple transparency, we prefer a clipping mask. */
5759 /* png_color_16 *image_bg; */
5760 Lisp_Object specified_bg
5761 = image_spec_value (img
->spec
, QCbackground
, NULL
);
5762 int shift
= (bit_depth
== 16) ? 0 : 8;
5764 if (STRINGP (specified_bg
))
5765 /* The user specified `:background', use that. */
5768 if (x_defined_color (f
, SSDATA (specified_bg
), &color
, 0))
5770 png_color_16 user_bg
;
5772 memset (&user_bg
, 0, sizeof user_bg
);
5773 user_bg
.red
= color
.red
>> shift
;
5774 user_bg
.green
= color
.green
>> shift
;
5775 user_bg
.blue
= color
.blue
>> shift
;
5777 fn_png_set_background (png_ptr
, &user_bg
,
5778 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
5783 /* We use the current frame background, ignoring any default
5784 background color set by the image. */
5785 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
5787 png_color_16 frame_background
;
5789 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
5790 x_query_color (f
, &color
);
5792 memset (&frame_background
, 0, sizeof frame_background
);
5793 frame_background
.red
= color
.red
>> shift
;
5794 frame_background
.green
= color
.green
>> shift
;
5795 frame_background
.blue
= color
.blue
>> shift
;
5796 #endif /* HAVE_X_WINDOWS */
5798 fn_png_set_background (png_ptr
, &frame_background
,
5799 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
5803 /* Update info structure. */
5804 fn_png_read_update_info (png_ptr
, info_ptr
);
5806 /* Get number of channels. Valid values are 1 for grayscale images
5807 and images with a palette, 2 for grayscale images with transparency
5808 information (alpha channel), 3 for RGB images, and 4 for RGB
5809 images with alpha channel, i.e. RGBA. If conversions above were
5810 sufficient we should only have 3 or 4 channels here. */
5811 channels
= fn_png_get_channels (png_ptr
, info_ptr
);
5812 xassert (channels
== 3 || channels
== 4);
5814 /* Number of bytes needed for one row of the image. */
5815 row_bytes
= fn_png_get_rowbytes (png_ptr
, info_ptr
);
5817 /* Allocate memory for the image. */
5818 pixels
= (png_byte
*) xmalloc (row_bytes
* height
* sizeof *pixels
);
5819 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
5820 for (i
= 0; i
< height
; ++i
)
5821 rows
[i
] = pixels
+ i
* row_bytes
;
5823 /* Read the entire image. */
5824 fn_png_read_image (png_ptr
, rows
);
5825 fn_png_read_end (png_ptr
, info_ptr
);
5832 /* Create the X image and pixmap. */
5833 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
5837 /* Create an image and pixmap serving as mask if the PNG image
5838 contains an alpha channel. */
5841 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
5842 &mask_img
, &img
->mask
))
5844 x_destroy_x_image (ximg
);
5845 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
5846 img
->pixmap
= NO_PIXMAP
;
5850 /* Fill the X image and mask from PNG data. */
5851 init_color_table ();
5853 for (y
= 0; y
< height
; ++y
)
5855 png_byte
*p
= rows
[y
];
5857 for (x
= 0; x
< width
; ++x
)
5864 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
5865 /* An alpha channel, aka mask channel, associates variable
5866 transparency with an image. Where other image formats
5867 support binary transparency---fully transparent or fully
5868 opaque---PNG allows up to 254 levels of partial transparency.
5869 The PNG library implements partial transparency by combining
5870 the image with a specified background color.
5872 I'm not sure how to handle this here nicely: because the
5873 background on which the image is displayed may change, for
5874 real alpha channel support, it would be necessary to create
5875 a new image for each possible background.
5877 What I'm doing now is that a mask is created if we have
5878 boolean transparency information. Otherwise I'm using
5879 the frame's background color to combine the image with. */
5884 XPutPixel (mask_img
, x
, y
, *p
> 0 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
);
5890 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
5891 /* Set IMG's background color from the PNG image, unless the user
5895 if (fn_png_get_bKGD (png_ptr
, info_ptr
, &bg
))
5897 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
5898 img
->background_valid
= 1;
5902 #ifdef COLOR_TABLE_SUPPORT
5903 /* Remember colors allocated for this image. */
5904 img
->colors
= colors_in_color_table (&img
->ncolors
);
5905 free_color_table ();
5906 #endif /* COLOR_TABLE_SUPPORT */
5909 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
5914 img
->height
= height
;
5916 /* Maybe fill in the background field while we have ximg handy.
5917 Casting avoids a GCC warning. */
5918 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
5920 /* Put the image into the pixmap, then free the X image and its buffer. */
5921 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
5922 x_destroy_x_image (ximg
);
5924 /* Same for the mask. */
5927 /* Fill in the background_transparent field while we have the
5928 mask handy. Casting avoids a GCC warning. */
5929 image_background_transparent (img
, f
, (XImagePtr_or_DC
)mask_img
);
5931 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
5932 x_destroy_x_image (mask_img
);
5938 #else /* HAVE_PNG */
5942 png_load (struct frame
*f
, struct image
*img
)
5944 return ns_load_image(f
, img
,
5945 image_spec_value (img
->spec
, QCfile
, NULL
),
5946 image_spec_value (img
->spec
, QCdata
, NULL
));
5948 #endif /* HAVE_NS */
5951 #endif /* !HAVE_PNG */
5955 /***********************************************************************
5957 ***********************************************************************/
5959 #if defined (HAVE_JPEG) || defined (HAVE_NS)
5961 static int jpeg_image_p (Lisp_Object object
);
5962 static int jpeg_load (struct frame
*f
, struct image
*img
);
5964 /* The symbol `jpeg' identifying images of this type. */
5968 /* Indices of image specification fields in gs_format, below. */
5970 enum jpeg_keyword_index
5979 JPEG_HEURISTIC_MASK
,
5985 /* Vector of image_keyword structures describing the format
5986 of valid user-defined image specifications. */
5988 static const struct image_keyword jpeg_format
[JPEG_LAST
] =
5990 {":type", IMAGE_SYMBOL_VALUE
, 1},
5991 {":data", IMAGE_STRING_VALUE
, 0},
5992 {":file", IMAGE_STRING_VALUE
, 0},
5993 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5994 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
5995 {":relief", IMAGE_INTEGER_VALUE
, 0},
5996 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5997 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5998 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5999 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
6002 /* Structure describing the image type `jpeg'. */
6004 static struct image_type jpeg_type
=
6013 /* Return non-zero if OBJECT is a valid JPEG image specification. */
6016 jpeg_image_p (Lisp_Object object
)
6018 struct image_keyword fmt
[JPEG_LAST
];
6020 memcpy (fmt
, jpeg_format
, sizeof fmt
);
6022 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
6025 /* Must specify either the :data or :file keyword. */
6026 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
6029 #endif /* HAVE_JPEG || HAVE_NS */
6033 /* Work around a warning about HAVE_STDLIB_H being redefined in
6035 #ifdef HAVE_STDLIB_H
6036 #define HAVE_STDLIB_H_1
6037 #undef HAVE_STDLIB_H
6038 #endif /* HAVE_STLIB_H */
6040 #if defined (HAVE_NTGUI) && !defined (__WIN32__)
6041 /* In older releases of the jpeg library, jpeglib.h will define boolean
6042 differently depending on __WIN32__, so make sure it is defined. */
6046 #include <jpeglib.h>
6049 #ifdef HAVE_STLIB_H_1
6050 #define HAVE_STDLIB_H 1
6055 /* JPEG library details. */
6056 DEF_IMGLIB_FN (void, jpeg_CreateDecompress
, (j_decompress_ptr
, int, size_t));
6057 DEF_IMGLIB_FN (boolean
, jpeg_start_decompress
, (j_decompress_ptr
));
6058 DEF_IMGLIB_FN (boolean
, jpeg_finish_decompress
, (j_decompress_ptr
));
6059 DEF_IMGLIB_FN (void, jpeg_destroy_decompress
, (j_decompress_ptr
));
6060 DEF_IMGLIB_FN (int, jpeg_read_header
, (j_decompress_ptr
, boolean
));
6061 DEF_IMGLIB_FN (JDIMENSION
, jpeg_read_scanlines
, (j_decompress_ptr
, JSAMPARRAY
, JDIMENSION
));
6062 DEF_IMGLIB_FN (struct jpeg_error_mgr
*, jpeg_std_error
, (struct jpeg_error_mgr
*));
6063 DEF_IMGLIB_FN (boolean
, jpeg_resync_to_restart
, (j_decompress_ptr
, int));
6066 init_jpeg_functions (Lisp_Object libraries
)
6070 if (!(library
= w32_delayed_load (libraries
, Qjpeg
)))
6073 LOAD_IMGLIB_FN (library
, jpeg_finish_decompress
);
6074 LOAD_IMGLIB_FN (library
, jpeg_read_scanlines
);
6075 LOAD_IMGLIB_FN (library
, jpeg_start_decompress
);
6076 LOAD_IMGLIB_FN (library
, jpeg_read_header
);
6077 LOAD_IMGLIB_FN (library
, jpeg_CreateDecompress
);
6078 LOAD_IMGLIB_FN (library
, jpeg_destroy_decompress
);
6079 LOAD_IMGLIB_FN (library
, jpeg_std_error
);
6080 LOAD_IMGLIB_FN (library
, jpeg_resync_to_restart
);
6084 /* Wrapper since we can't directly assign the function pointer
6085 to another function pointer that was declared more completely easily. */
6087 jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo
, int desired
)
6089 return fn_jpeg_resync_to_restart (cinfo
, desired
);
6094 #define fn_jpeg_CreateDecompress(a,b,c) jpeg_create_decompress(a)
6095 #define fn_jpeg_start_decompress jpeg_start_decompress
6096 #define fn_jpeg_finish_decompress jpeg_finish_decompress
6097 #define fn_jpeg_destroy_decompress jpeg_destroy_decompress
6098 #define fn_jpeg_read_header jpeg_read_header
6099 #define fn_jpeg_read_scanlines jpeg_read_scanlines
6100 #define fn_jpeg_std_error jpeg_std_error
6101 #define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart
6103 #endif /* HAVE_NTGUI */
6105 struct my_jpeg_error_mgr
6107 struct jpeg_error_mgr pub
;
6108 jmp_buf setjmp_buffer
;
6113 my_error_exit (j_common_ptr cinfo
)
6115 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
6116 longjmp (mgr
->setjmp_buffer
, 1);
6120 /* Init source method for JPEG data source manager. Called by
6121 jpeg_read_header() before any data is actually read. See
6122 libjpeg.doc from the JPEG lib distribution. */
6125 our_common_init_source (j_decompress_ptr cinfo
)
6130 /* Method to terminate data source. Called by
6131 jpeg_finish_decompress() after all data has been processed. */
6134 our_common_term_source (j_decompress_ptr cinfo
)
6139 /* Fill input buffer method for JPEG data source manager. Called
6140 whenever more data is needed. We read the whole image in one step,
6141 so this only adds a fake end of input marker at the end. */
6143 static JOCTET our_memory_buffer
[2];
6146 our_memory_fill_input_buffer (j_decompress_ptr cinfo
)
6148 /* Insert a fake EOI marker. */
6149 struct jpeg_source_mgr
*src
= cinfo
->src
;
6151 our_memory_buffer
[0] = (JOCTET
) 0xFF;
6152 our_memory_buffer
[1] = (JOCTET
) JPEG_EOI
;
6154 src
->next_input_byte
= our_memory_buffer
;
6155 src
->bytes_in_buffer
= 2;
6160 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6161 is the JPEG data source manager. */
6164 our_memory_skip_input_data (j_decompress_ptr cinfo
, long int num_bytes
)
6166 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6170 if (num_bytes
> src
->bytes_in_buffer
)
6171 ERREXIT (cinfo
, JERR_INPUT_EOF
);
6173 src
->bytes_in_buffer
-= num_bytes
;
6174 src
->next_input_byte
+= num_bytes
;
6179 /* Set up the JPEG lib for reading an image from DATA which contains
6180 LEN bytes. CINFO is the decompression info structure created for
6181 reading the image. */
6184 jpeg_memory_src (j_decompress_ptr cinfo
, JOCTET
*data
, unsigned int len
)
6186 struct jpeg_source_mgr
*src
;
6188 if (cinfo
->src
== NULL
)
6190 /* First time for this JPEG object? */
6191 cinfo
->src
= (struct jpeg_source_mgr
*)
6192 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6193 sizeof (struct jpeg_source_mgr
));
6194 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6195 src
->next_input_byte
= data
;
6198 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6199 src
->init_source
= our_common_init_source
;
6200 src
->fill_input_buffer
= our_memory_fill_input_buffer
;
6201 src
->skip_input_data
= our_memory_skip_input_data
;
6202 src
->resync_to_restart
= jpeg_resync_to_restart_wrapper
; /* Use default method. */
6203 src
->term_source
= our_common_term_source
;
6204 src
->bytes_in_buffer
= len
;
6205 src
->next_input_byte
= data
;
6209 struct jpeg_stdio_mgr
6211 struct jpeg_source_mgr mgr
;
6218 /* Size of buffer to read JPEG from file.
6219 Not too big, as we want to use alloc_small. */
6220 #define JPEG_STDIO_BUFFER_SIZE 8192
6223 /* Fill input buffer method for JPEG data source manager. Called
6224 whenever more data is needed. The data is read from a FILE *. */
6227 our_stdio_fill_input_buffer (j_decompress_ptr cinfo
)
6229 struct jpeg_stdio_mgr
*src
;
6231 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6236 bytes
= fread (src
->buffer
, 1, JPEG_STDIO_BUFFER_SIZE
, src
->file
);
6238 src
->mgr
.bytes_in_buffer
= bytes
;
6241 WARNMS (cinfo
, JWRN_JPEG_EOF
);
6243 src
->buffer
[0] = (JOCTET
) 0xFF;
6244 src
->buffer
[1] = (JOCTET
) JPEG_EOI
;
6245 src
->mgr
.bytes_in_buffer
= 2;
6247 src
->mgr
.next_input_byte
= src
->buffer
;
6254 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6255 is the JPEG data source manager. */
6258 our_stdio_skip_input_data (j_decompress_ptr cinfo
, long int num_bytes
)
6260 struct jpeg_stdio_mgr
*src
;
6261 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6263 while (num_bytes
> 0 && !src
->finished
)
6265 if (num_bytes
<= src
->mgr
.bytes_in_buffer
)
6267 src
->mgr
.bytes_in_buffer
-= num_bytes
;
6268 src
->mgr
.next_input_byte
+= num_bytes
;
6273 num_bytes
-= src
->mgr
.bytes_in_buffer
;
6274 src
->mgr
.bytes_in_buffer
= 0;
6275 src
->mgr
.next_input_byte
= NULL
;
6277 our_stdio_fill_input_buffer (cinfo
);
6283 /* Set up the JPEG lib for reading an image from a FILE *.
6284 CINFO is the decompression info structure created for
6285 reading the image. */
6288 jpeg_file_src (j_decompress_ptr cinfo
, FILE *fp
)
6290 struct jpeg_stdio_mgr
*src
;
6292 if (cinfo
->src
!= NULL
)
6293 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6296 /* First time for this JPEG object? */
6297 cinfo
->src
= (struct jpeg_source_mgr
*)
6298 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6299 sizeof (struct jpeg_stdio_mgr
));
6300 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6301 src
->buffer
= (JOCTET
*)
6302 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6303 JPEG_STDIO_BUFFER_SIZE
);
6308 src
->mgr
.init_source
= our_common_init_source
;
6309 src
->mgr
.fill_input_buffer
= our_stdio_fill_input_buffer
;
6310 src
->mgr
.skip_input_data
= our_stdio_skip_input_data
;
6311 src
->mgr
.resync_to_restart
= jpeg_resync_to_restart_wrapper
; /* Use default method. */
6312 src
->mgr
.term_source
= our_common_term_source
;
6313 src
->mgr
.bytes_in_buffer
= 0;
6314 src
->mgr
.next_input_byte
= NULL
;
6318 /* Load image IMG for use on frame F. Patterned after example.c
6319 from the JPEG lib. */
6322 jpeg_load (struct frame
*f
, struct image
*img
)
6324 struct jpeg_decompress_struct cinfo
;
6325 struct my_jpeg_error_mgr mgr
;
6326 Lisp_Object file
, specified_file
;
6327 Lisp_Object specified_data
;
6328 FILE * volatile fp
= NULL
;
6330 int row_stride
, x
, y
;
6331 XImagePtr ximg
= NULL
;
6333 unsigned long *colors
;
6336 /* Open the JPEG file. */
6337 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6338 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6340 if (NILP (specified_data
))
6342 file
= x_find_image_file (specified_file
);
6343 if (!STRINGP (file
))
6345 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6349 fp
= fopen (SSDATA (file
), "rb");
6352 image_error ("Cannot open `%s'", file
, Qnil
);
6356 else if (!STRINGP (specified_data
))
6358 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
6362 /* Customize libjpeg's error handling to call my_error_exit when an
6363 error is detected. This function will perform a longjmp. */
6364 cinfo
.err
= fn_jpeg_std_error (&mgr
.pub
);
6365 mgr
.pub
.error_exit
= my_error_exit
;
6367 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
6371 /* Called from my_error_exit. Display a JPEG error. */
6372 char buffer
[JMSG_LENGTH_MAX
];
6373 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buffer
);
6374 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
6375 build_string (buffer
));
6378 /* Close the input file and destroy the JPEG object. */
6380 fclose ((FILE *) fp
);
6381 fn_jpeg_destroy_decompress (&cinfo
);
6383 /* If we already have an XImage, free that. */
6384 x_destroy_x_image (ximg
);
6386 /* Free pixmap and colors. */
6387 x_clear_image (f
, img
);
6391 /* Create the JPEG decompression object. Let it read from fp.
6392 Read the JPEG image header. */
6393 fn_jpeg_CreateDecompress (&cinfo
, JPEG_LIB_VERSION
, sizeof (cinfo
));
6395 if (NILP (specified_data
))
6396 jpeg_file_src (&cinfo
, (FILE *) fp
);
6398 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
6399 SBYTES (specified_data
));
6401 fn_jpeg_read_header (&cinfo
, 1);
6403 /* Customize decompression so that color quantization will be used.
6404 Start decompression. */
6405 cinfo
.quantize_colors
= 1;
6406 fn_jpeg_start_decompress (&cinfo
);
6407 width
= img
->width
= cinfo
.output_width
;
6408 height
= img
->height
= cinfo
.output_height
;
6410 if (!check_image_size (f
, width
, height
))
6412 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
6413 longjmp (mgr
.setjmp_buffer
, 2);
6416 /* Create X image and pixmap. */
6417 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
6418 longjmp (mgr
.setjmp_buffer
, 2);
6420 /* Allocate colors. When color quantization is used,
6421 cinfo.actual_number_of_colors has been set with the number of
6422 colors generated, and cinfo.colormap is a two-dimensional array
6423 of color indices in the range 0..cinfo.actual_number_of_colors.
6424 No more than 255 colors will be generated. */
6428 if (cinfo
.out_color_components
> 2)
6429 ir
= 0, ig
= 1, ib
= 2;
6430 else if (cinfo
.out_color_components
> 1)
6431 ir
= 0, ig
= 1, ib
= 0;
6433 ir
= 0, ig
= 0, ib
= 0;
6435 /* Use the color table mechanism because it handles colors that
6436 cannot be allocated nicely. Such colors will be replaced with
6437 a default color, and we don't have to care about which colors
6438 can be freed safely, and which can't. */
6439 init_color_table ();
6440 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
6443 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
6445 /* Multiply RGB values with 255 because X expects RGB values
6446 in the range 0..0xffff. */
6447 int r
= cinfo
.colormap
[ir
][i
] << 8;
6448 int g
= cinfo
.colormap
[ig
][i
] << 8;
6449 int b
= cinfo
.colormap
[ib
][i
] << 8;
6450 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
6453 #ifdef COLOR_TABLE_SUPPORT
6454 /* Remember those colors actually allocated. */
6455 img
->colors
= colors_in_color_table (&img
->ncolors
);
6456 free_color_table ();
6457 #endif /* COLOR_TABLE_SUPPORT */
6461 row_stride
= width
* cinfo
.output_components
;
6462 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
6464 for (y
= 0; y
< height
; ++y
)
6466 fn_jpeg_read_scanlines (&cinfo
, buffer
, 1);
6467 for (x
= 0; x
< cinfo
.output_width
; ++x
)
6468 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
6472 fn_jpeg_finish_decompress (&cinfo
);
6473 fn_jpeg_destroy_decompress (&cinfo
);
6475 fclose ((FILE *) fp
);
6477 /* Maybe fill in the background field while we have ximg handy. */
6478 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6479 /* Casting avoids a GCC warning. */
6480 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6482 /* Put the image into the pixmap. */
6483 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6484 x_destroy_x_image (ximg
);
6488 #else /* HAVE_JPEG */
6492 jpeg_load (struct frame
*f
, struct image
*img
)
6494 return ns_load_image (f
, img
,
6495 image_spec_value (img
->spec
, QCfile
, NULL
),
6496 image_spec_value (img
->spec
, QCdata
, NULL
));
6498 #endif /* HAVE_NS */
6500 #endif /* !HAVE_JPEG */
6504 /***********************************************************************
6506 ***********************************************************************/
6508 #if defined (HAVE_TIFF) || defined (HAVE_NS)
6510 static int tiff_image_p (Lisp_Object object
);
6511 static int tiff_load (struct frame
*f
, struct image
*img
);
6513 /* The symbol `tiff' identifying images of this type. */
6517 /* Indices of image specification fields in tiff_format, below. */
6519 enum tiff_keyword_index
6528 TIFF_HEURISTIC_MASK
,
6535 /* Vector of image_keyword structures describing the format
6536 of valid user-defined image specifications. */
6538 static const struct image_keyword tiff_format
[TIFF_LAST
] =
6540 {":type", IMAGE_SYMBOL_VALUE
, 1},
6541 {":data", IMAGE_STRING_VALUE
, 0},
6542 {":file", IMAGE_STRING_VALUE
, 0},
6543 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6544 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6545 {":relief", IMAGE_INTEGER_VALUE
, 0},
6546 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6547 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6548 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6549 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
6550 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0}
6553 /* Structure describing the image type `tiff'. */
6555 static struct image_type tiff_type
=
6564 /* Return non-zero if OBJECT is a valid TIFF image specification. */
6567 tiff_image_p (Lisp_Object object
)
6569 struct image_keyword fmt
[TIFF_LAST
];
6570 memcpy (fmt
, tiff_format
, sizeof fmt
);
6572 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
6575 /* Must specify either the :data or :file keyword. */
6576 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
6579 #endif /* HAVE_TIFF || HAVE_NS */
6587 /* TIFF library details. */
6588 DEF_IMGLIB_FN (TIFFErrorHandler
, TIFFSetErrorHandler
, (TIFFErrorHandler
));
6589 DEF_IMGLIB_FN (TIFFErrorHandler
, TIFFSetWarningHandler
, (TIFFErrorHandler
));
6590 DEF_IMGLIB_FN (TIFF
*, TIFFOpen
, (const char *, const char *));
6591 DEF_IMGLIB_FN (TIFF
*, TIFFClientOpen
, (const char *, const char *, thandle_t
,
6592 TIFFReadWriteProc
, TIFFReadWriteProc
,
6593 TIFFSeekProc
, TIFFCloseProc
, TIFFSizeProc
,
6594 TIFFMapFileProc
, TIFFUnmapFileProc
));
6595 DEF_IMGLIB_FN (int, TIFFGetField
, (TIFF
*, ttag_t
, ...));
6596 DEF_IMGLIB_FN (int, TIFFReadRGBAImage
, (TIFF
*, uint32
, uint32
, uint32
*, int));
6597 DEF_IMGLIB_FN (void, TIFFClose
, (TIFF
*));
6598 DEF_IMGLIB_FN (int, TIFFSetDirectory
, (TIFF
*, tdir_t
));
6601 init_tiff_functions (Lisp_Object libraries
)
6605 if (!(library
= w32_delayed_load (libraries
, Qtiff
)))
6608 LOAD_IMGLIB_FN (library
, TIFFSetErrorHandler
);
6609 LOAD_IMGLIB_FN (library
, TIFFSetWarningHandler
);
6610 LOAD_IMGLIB_FN (library
, TIFFOpen
);
6611 LOAD_IMGLIB_FN (library
, TIFFClientOpen
);
6612 LOAD_IMGLIB_FN (library
, TIFFGetField
);
6613 LOAD_IMGLIB_FN (library
, TIFFReadRGBAImage
);
6614 LOAD_IMGLIB_FN (library
, TIFFClose
);
6615 LOAD_IMGLIB_FN (library
, TIFFSetDirectory
);
6621 #define fn_TIFFSetErrorHandler TIFFSetErrorHandler
6622 #define fn_TIFFSetWarningHandler TIFFSetWarningHandler
6623 #define fn_TIFFOpen TIFFOpen
6624 #define fn_TIFFClientOpen TIFFClientOpen
6625 #define fn_TIFFGetField TIFFGetField
6626 #define fn_TIFFReadRGBAImage TIFFReadRGBAImage
6627 #define fn_TIFFClose TIFFClose
6628 #define fn_TIFFSetDirectory TIFFSetDirectory
6629 #endif /* HAVE_NTGUI */
6632 /* Reading from a memory buffer for TIFF images Based on the PNG
6633 memory source, but we have to provide a lot of extra functions.
6636 We really only need to implement read and seek, but I am not
6637 convinced that the TIFF library is smart enough not to destroy
6638 itself if we only hand it the function pointers we need to
6643 unsigned char *bytes
;
6650 tiff_read_from_memory (thandle_t data
, tdata_t buf
, tsize_t size
)
6652 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6654 if (size
> src
->len
- src
->index
)
6656 memcpy (buf
, src
->bytes
+ src
->index
, size
);
6662 tiff_write_from_memory (thandle_t data
, tdata_t buf
, tsize_t size
)
6668 tiff_seek_in_memory (thandle_t data
, toff_t off
, int whence
)
6670 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6675 case SEEK_SET
: /* Go from beginning of source. */
6679 case SEEK_END
: /* Go from end of source. */
6680 idx
= src
->len
+ off
;
6683 case SEEK_CUR
: /* Go from current position. */
6684 idx
= src
->index
+ off
;
6687 default: /* Invalid `whence'. */
6691 if (idx
> src
->len
|| idx
< 0)
6699 tiff_close_memory (thandle_t data
)
6706 tiff_mmap_memory (thandle_t data
, tdata_t
*pbase
, toff_t
*psize
)
6708 /* It is already _IN_ memory. */
6713 tiff_unmap_memory (thandle_t data
, tdata_t base
, toff_t size
)
6715 /* We don't need to do this. */
6719 tiff_size_of_memory (thandle_t data
)
6721 return ((tiff_memory_source
*) data
)->len
;
6726 tiff_error_handler (const char *title
, const char *format
, va_list ap
)
6731 len
= sprintf (buf
, "TIFF error: %s ", title
);
6732 vsprintf (buf
+ len
, format
, ap
);
6733 add_to_log (buf
, Qnil
, Qnil
);
6738 tiff_warning_handler (const char *title
, const char *format
, va_list ap
)
6743 len
= sprintf (buf
, "TIFF warning: %s ", title
);
6744 vsprintf (buf
+ len
, format
, ap
);
6745 add_to_log (buf
, Qnil
, Qnil
);
6749 /* Load TIFF image IMG for use on frame F. Value is non-zero if
6753 tiff_load (struct frame
*f
, struct image
*img
)
6755 Lisp_Object file
, specified_file
;
6756 Lisp_Object specified_data
;
6758 int width
, height
, x
, y
, count
;
6762 tiff_memory_source memsrc
;
6765 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6766 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6768 fn_TIFFSetErrorHandler (tiff_error_handler
);
6769 fn_TIFFSetWarningHandler (tiff_warning_handler
);
6771 if (NILP (specified_data
))
6773 /* Read from a file */
6774 file
= x_find_image_file (specified_file
);
6775 if (!STRINGP (file
))
6777 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6781 /* Try to open the image file. */
6782 tiff
= fn_TIFFOpen (SSDATA (file
), "r");
6785 image_error ("Cannot open `%s'", file
, Qnil
);
6791 if (!STRINGP (specified_data
))
6793 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
6797 /* Memory source! */
6798 memsrc
.bytes
= SDATA (specified_data
);
6799 memsrc
.len
= SBYTES (specified_data
);
6802 tiff
= fn_TIFFClientOpen ("memory_source", "r", (thandle_t
)&memsrc
,
6803 (TIFFReadWriteProc
) tiff_read_from_memory
,
6804 (TIFFReadWriteProc
) tiff_write_from_memory
,
6805 tiff_seek_in_memory
,
6807 tiff_size_of_memory
,
6813 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
6818 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
6819 if (INTEGERP (image
))
6821 int ino
= XFASTINT (image
);
6822 if (!fn_TIFFSetDirectory (tiff
, ino
))
6824 image_error ("Invalid image number `%s' in image `%s'",
6826 fn_TIFFClose (tiff
);
6831 /* Get width and height of the image, and allocate a raster buffer
6832 of width x height 32-bit values. */
6833 fn_TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
6834 fn_TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
6836 if (!check_image_size (f
, width
, height
))
6838 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
6839 fn_TIFFClose (tiff
);
6843 buf
= (uint32
*) xmalloc (width
* height
* sizeof *buf
);
6845 rc
= fn_TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
6847 /* Count the number of images in the file. */
6848 for (count
= 1, rc2
= 1; rc2
; count
++)
6849 rc2
= fn_TIFFSetDirectory (tiff
, count
);
6852 img
->data
.lisp_val
= Fcons (Qcount
,
6853 Fcons (make_number (count
),
6854 img
->data
.lisp_val
));
6856 fn_TIFFClose (tiff
);
6859 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
6864 /* Create the X image and pixmap. */
6865 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
6871 /* Initialize the color table. */
6872 init_color_table ();
6874 /* Process the pixel raster. Origin is in the lower-left corner. */
6875 for (y
= 0; y
< height
; ++y
)
6877 uint32
*row
= buf
+ y
* width
;
6879 for (x
= 0; x
< width
; ++x
)
6881 uint32 abgr
= row
[x
];
6882 int r
= TIFFGetR (abgr
) << 8;
6883 int g
= TIFFGetG (abgr
) << 8;
6884 int b
= TIFFGetB (abgr
) << 8;
6885 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
6889 #ifdef COLOR_TABLE_SUPPORT
6890 /* Remember the colors allocated for the image. Free the color table. */
6891 img
->colors
= colors_in_color_table (&img
->ncolors
);
6892 free_color_table ();
6893 #endif /* COLOR_TABLE_SUPPORT */
6896 img
->height
= height
;
6898 /* Maybe fill in the background field while we have ximg handy. */
6899 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6900 /* Casting avoids a GCC warning on W32. */
6901 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6903 /* Put the image into the pixmap, then free the X image and its buffer. */
6904 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6905 x_destroy_x_image (ximg
);
6911 #else /* HAVE_TIFF */
6915 tiff_load (struct frame
*f
, struct image
*img
)
6917 return ns_load_image (f
, img
,
6918 image_spec_value (img
->spec
, QCfile
, NULL
),
6919 image_spec_value (img
->spec
, QCdata
, NULL
));
6921 #endif /* HAVE_NS */
6923 #endif /* !HAVE_TIFF */
6927 /***********************************************************************
6929 ***********************************************************************/
6931 #if defined (HAVE_GIF) || defined (HAVE_NS)
6933 static int gif_image_p (Lisp_Object object
);
6934 static int gif_load (struct frame
*f
, struct image
*img
);
6935 static void gif_clear_image (struct frame
*f
, struct image
*img
);
6937 /* The symbol `gif' identifying images of this type. */
6941 /* Indices of image specification fields in gif_format, below. */
6943 enum gif_keyword_index
6959 /* Vector of image_keyword structures describing the format
6960 of valid user-defined image specifications. */
6962 static const struct image_keyword gif_format
[GIF_LAST
] =
6964 {":type", IMAGE_SYMBOL_VALUE
, 1},
6965 {":data", IMAGE_STRING_VALUE
, 0},
6966 {":file", IMAGE_STRING_VALUE
, 0},
6967 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6968 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
6969 {":relief", IMAGE_INTEGER_VALUE
, 0},
6970 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6971 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6972 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6973 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
6974 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
6977 /* Structure describing the image type `gif'. */
6979 static struct image_type gif_type
=
6988 /* Free X resources of GIF image IMG which is used on frame F. */
6991 gif_clear_image (struct frame
*f
, struct image
*img
)
6993 /* IMG->data.ptr_val may contain metadata with extension data. */
6994 img
->data
.lisp_val
= Qnil
;
6995 x_clear_image (f
, img
);
6998 /* Return non-zero if OBJECT is a valid GIF image specification. */
7001 gif_image_p (Lisp_Object object
)
7003 struct image_keyword fmt
[GIF_LAST
];
7004 memcpy (fmt
, gif_format
, sizeof fmt
);
7006 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
7009 /* Must specify either the :data or :file keyword. */
7010 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
7013 #endif /* HAVE_GIF */
7017 #if defined (HAVE_NTGUI)
7018 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
7019 Undefine before redefining to avoid a preprocessor warning. */
7023 /* avoid conflict with QuickdrawText.h */
7024 #define DrawText gif_DrawText
7025 #include <gif_lib.h>
7028 #else /* HAVE_NTGUI */
7030 #include <gif_lib.h>
7032 #endif /* HAVE_NTGUI */
7037 /* GIF library details. */
7038 DEF_IMGLIB_FN (int, DGifCloseFile
, (GifFileType
*));
7039 DEF_IMGLIB_FN (int, DGifSlurp
, (GifFileType
*));
7040 DEF_IMGLIB_FN (GifFileType
*, DGifOpen
, (void *, InputFunc
));
7041 DEF_IMGLIB_FN (GifFileType
*, DGifOpenFileName
, (const char *));
7044 init_gif_functions (Lisp_Object libraries
)
7048 if (!(library
= w32_delayed_load (libraries
, Qgif
)))
7051 LOAD_IMGLIB_FN (library
, DGifCloseFile
);
7052 LOAD_IMGLIB_FN (library
, DGifSlurp
);
7053 LOAD_IMGLIB_FN (library
, DGifOpen
);
7054 LOAD_IMGLIB_FN (library
, DGifOpenFileName
);
7060 #define fn_DGifCloseFile DGifCloseFile
7061 #define fn_DGifSlurp DGifSlurp
7062 #define fn_DGifOpen DGifOpen
7063 #define fn_DGifOpenFileName DGifOpenFileName
7065 #endif /* HAVE_NTGUI */
7067 /* Reading a GIF image from memory
7068 Based on the PNG memory stuff to a certain extent. */
7072 unsigned char *bytes
;
7078 /* Make the current memory source available to gif_read_from_memory.
7079 It's done this way because not all versions of libungif support
7080 a UserData field in the GifFileType structure. */
7081 static gif_memory_source
*current_gif_memory_src
;
7084 gif_read_from_memory (GifFileType
*file
, GifByteType
*buf
, int len
)
7086 gif_memory_source
*src
= current_gif_memory_src
;
7088 if (len
> src
->len
- src
->index
)
7091 memcpy (buf
, src
->bytes
+ src
->index
, len
);
7097 /* Load GIF image IMG for use on frame F. Value is non-zero if
7100 static const int interlace_start
[] = {0, 4, 2, 1};
7101 static const int interlace_increment
[] = {8, 8, 4, 2};
7103 #define GIF_LOCAL_DESCRIPTOR_EXTENSION 249
7106 gif_load (struct frame
*f
, struct image
*img
)
7108 Lisp_Object file
, specified_file
;
7109 Lisp_Object specified_data
;
7110 int rc
, width
, height
, x
, y
, i
;
7111 boolean transparent_p
;
7113 ColorMapObject
*gif_color_map
;
7114 unsigned long pixel_colors
[256];
7117 int ino
, image_height
, image_width
;
7118 gif_memory_source memsrc
;
7119 unsigned char *raster
;
7120 unsigned int transparency_color_index
;
7122 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7123 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7125 if (NILP (specified_data
))
7127 file
= x_find_image_file (specified_file
);
7128 if (!STRINGP (file
))
7130 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7134 /* Open the GIF file. */
7135 gif
= fn_DGifOpenFileName (SDATA (file
));
7138 image_error ("Cannot open `%s'", file
, Qnil
);
7144 if (!STRINGP (specified_data
))
7146 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
7150 /* Read from memory! */
7151 current_gif_memory_src
= &memsrc
;
7152 memsrc
.bytes
= SDATA (specified_data
);
7153 memsrc
.len
= SBYTES (specified_data
);
7156 gif
= fn_DGifOpen (&memsrc
, gif_read_from_memory
);
7159 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
7164 /* Before reading entire contents, check the declared image size. */
7165 if (!check_image_size (f
, gif
->SWidth
, gif
->SHeight
))
7167 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7168 fn_DGifCloseFile (gif
);
7172 /* Read entire contents. */
7173 rc
= fn_DGifSlurp (gif
);
7174 if (rc
== GIF_ERROR
)
7176 image_error ("Error reading `%s'", img
->spec
, Qnil
);
7177 fn_DGifCloseFile (gif
);
7181 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
7182 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
7183 if (ino
>= gif
->ImageCount
)
7185 image_error ("Invalid image number `%s' in image `%s'",
7187 fn_DGifCloseFile (gif
);
7191 for (i
= 0; i
< gif
->SavedImages
[ino
].ExtensionBlockCount
; i
++)
7192 if ((gif
->SavedImages
[ino
].ExtensionBlocks
[i
].Function
7193 == GIF_LOCAL_DESCRIPTOR_EXTENSION
)
7194 && gif
->SavedImages
[ino
].ExtensionBlocks
[i
].ByteCount
== 4
7195 /* Transparency enabled? */
7196 && gif
->SavedImages
[ino
].ExtensionBlocks
[i
].Bytes
[0] & 1)
7199 transparency_color_index
7200 = (unsigned char) gif
->SavedImages
[ino
].ExtensionBlocks
[i
].Bytes
[3];
7203 img
->corners
[TOP_CORNER
] = gif
->SavedImages
[ino
].ImageDesc
.Top
;
7204 img
->corners
[LEFT_CORNER
] = gif
->SavedImages
[ino
].ImageDesc
.Left
;
7205 image_height
= gif
->SavedImages
[ino
].ImageDesc
.Height
;
7206 img
->corners
[BOT_CORNER
] = img
->corners
[TOP_CORNER
] + image_height
;
7207 image_width
= gif
->SavedImages
[ino
].ImageDesc
.Width
;
7208 img
->corners
[RIGHT_CORNER
] = img
->corners
[LEFT_CORNER
] + image_width
;
7210 width
= img
->width
= max (gif
->SWidth
,
7211 max (gif
->Image
.Left
+ gif
->Image
.Width
,
7212 img
->corners
[RIGHT_CORNER
]));
7213 height
= img
->height
= max (gif
->SHeight
,
7214 max (gif
->Image
.Top
+ gif
->Image
.Height
,
7215 img
->corners
[BOT_CORNER
]));
7217 if (!check_image_size (f
, width
, height
))
7219 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7220 fn_DGifCloseFile (gif
);
7224 /* Create the X image and pixmap. */
7225 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
7227 fn_DGifCloseFile (gif
);
7231 /* Allocate colors. */
7232 gif_color_map
= gif
->SavedImages
[ino
].ImageDesc
.ColorMap
;
7234 gif_color_map
= gif
->SColorMap
;
7235 init_color_table ();
7236 memset (pixel_colors
, 0, sizeof pixel_colors
);
7239 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
7241 if (transparent_p
&& transparency_color_index
== i
)
7243 Lisp_Object specified_bg
7244 = image_spec_value (img
->spec
, QCbackground
, NULL
);
7245 pixel_colors
[i
] = STRINGP (specified_bg
)
7246 ? x_alloc_image_color (f
, img
, specified_bg
,
7247 FRAME_BACKGROUND_PIXEL (f
))
7248 : FRAME_BACKGROUND_PIXEL (f
);
7252 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
7253 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
7254 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
7255 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
7259 #ifdef COLOR_TABLE_SUPPORT
7260 img
->colors
= colors_in_color_table (&img
->ncolors
);
7261 free_color_table ();
7262 #endif /* COLOR_TABLE_SUPPORT */
7264 /* Clear the part of the screen image that are not covered by
7265 the image from the GIF file. Full animated GIF support
7266 requires more than can be done here (see the gif89 spec,
7267 disposal methods). Let's simply assume that the part
7268 not covered by a sub-image is in the frame's background color. */
7269 for (y
= 0; y
< img
->corners
[TOP_CORNER
]; ++y
)
7270 for (x
= 0; x
< width
; ++x
)
7271 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7273 for (y
= img
->corners
[BOT_CORNER
]; y
< height
; ++y
)
7274 for (x
= 0; x
< width
; ++x
)
7275 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7277 for (y
= img
->corners
[TOP_CORNER
]; y
< img
->corners
[BOT_CORNER
]; ++y
)
7279 for (x
= 0; x
< img
->corners
[LEFT_CORNER
]; ++x
)
7280 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7281 for (x
= img
->corners
[RIGHT_CORNER
]; x
< width
; ++x
)
7282 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7285 /* Read the GIF image into the X image. We use a local variable
7286 `raster' here because RasterBits below is a char *, and invites
7287 problems with bytes >= 0x80. */
7288 raster
= (unsigned char *) gif
->SavedImages
[ino
].RasterBits
;
7290 if (gif
->SavedImages
[ino
].ImageDesc
.Interlace
)
7293 int row
= interlace_start
[0];
7297 for (y
= 0; y
< image_height
; y
++)
7299 if (row
>= image_height
)
7301 row
= interlace_start
[++pass
];
7302 while (row
>= image_height
)
7303 row
= interlace_start
[++pass
];
7306 for (x
= 0; x
< image_width
; x
++)
7308 int i
= raster
[(y
* image_width
) + x
];
7309 XPutPixel (ximg
, x
+ img
->corners
[LEFT_CORNER
],
7310 row
+ img
->corners
[TOP_CORNER
], pixel_colors
[i
]);
7313 row
+= interlace_increment
[pass
];
7318 for (y
= 0; y
< image_height
; ++y
)
7319 for (x
= 0; x
< image_width
; ++x
)
7321 int i
= raster
[y
* image_width
+ x
];
7322 XPutPixel (ximg
, x
+ img
->corners
[LEFT_CORNER
],
7323 y
+ img
->corners
[TOP_CORNER
], pixel_colors
[i
]);
7327 /* Save GIF image extension data for `image-metadata'.
7328 Format is (count IMAGES extension-data (FUNCTION "BYTES" ...)). */
7329 img
->data
.lisp_val
= Qnil
;
7330 if (gif
->SavedImages
[ino
].ExtensionBlockCount
> 0)
7332 ExtensionBlock
*ext
= gif
->SavedImages
[ino
].ExtensionBlocks
;
7333 for (i
= 0; i
< gif
->SavedImages
[ino
].ExtensionBlockCount
; i
++, ext
++)
7334 /* Append (... FUNCTION "BYTES") */
7335 img
->data
.lisp_val
= Fcons (make_unibyte_string (ext
->Bytes
, ext
->ByteCount
),
7336 Fcons (make_number (ext
->Function
),
7337 img
->data
.lisp_val
));
7338 img
->data
.lisp_val
= Fcons (Qextension_data
,
7339 Fcons (Fnreverse (img
->data
.lisp_val
),
7342 if (gif
->ImageCount
> 1)
7343 img
->data
.lisp_val
= Fcons (Qcount
,
7344 Fcons (make_number (gif
->ImageCount
),
7345 img
->data
.lisp_val
));
7347 fn_DGifCloseFile (gif
);
7349 /* Maybe fill in the background field while we have ximg handy. */
7350 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7351 /* Casting avoids a GCC warning. */
7352 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
7354 /* Put the image into the pixmap, then free the X image and its buffer. */
7355 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7356 x_destroy_x_image (ximg
);
7361 #else /* !HAVE_GIF */
7365 gif_load (struct frame
*f
, struct image
*img
)
7367 return ns_load_image (f
, img
,
7368 image_spec_value (img
->spec
, QCfile
, NULL
),
7369 image_spec_value (img
->spec
, QCdata
, NULL
));
7371 #endif /* HAVE_NS */
7373 #endif /* HAVE_GIF */
7376 /***********************************************************************
7378 ***********************************************************************/
7379 #if defined (HAVE_IMAGEMAGICK)
7381 /* The symbol `imagemagick' identifying images of this type. */
7383 Lisp_Object Qimagemagick
;
7384 /* Indices of image specification fields in imagemagick_format, below. */
7386 enum imagemagick_keyword_index
7394 IMAGEMAGICK_ALGORITHM
,
7395 IMAGEMAGICK_HEURISTIC_MASK
,
7397 IMAGEMAGICK_BACKGROUND
,
7400 IMAGEMAGICK_ROTATION
,
7405 /* Vector of image_keyword structures describing the format
7406 of valid user-defined image specifications. */
7408 static struct image_keyword imagemagick_format
[IMAGEMAGICK_LAST
] =
7410 {":type", IMAGE_SYMBOL_VALUE
, 1},
7411 {":data", IMAGE_STRING_VALUE
, 0},
7412 {":file", IMAGE_STRING_VALUE
, 0},
7413 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7414 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7415 {":relief", IMAGE_INTEGER_VALUE
, 0},
7416 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7417 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7418 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7419 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
7420 {":height", IMAGE_INTEGER_VALUE
, 0},
7421 {":width", IMAGE_INTEGER_VALUE
, 0},
7422 {":rotation", IMAGE_NUMBER_VALUE
, 0},
7423 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
7425 /* Free X resources of imagemagick image IMG which is used on frame F. */
7428 imagemagick_clear_image (struct frame
*f
,
7431 x_clear_image (f
, img
);
7436 /* Return non-zero if OBJECT is a valid IMAGEMAGICK image specification. Do
7437 this by calling parse_image_spec and supplying the keywords that
7438 identify the IMAGEMAGICK format. */
7441 imagemagick_image_p (Lisp_Object object
)
7443 struct image_keyword fmt
[IMAGEMAGICK_LAST
];
7444 memcpy (fmt
, imagemagick_format
, sizeof fmt
);
7446 if (!parse_image_spec (object
, fmt
, IMAGEMAGICK_LAST
, Qimagemagick
))
7449 /* Must specify either the :data or :file keyword. */
7450 return fmt
[IMAGEMAGICK_FILE
].count
+ fmt
[IMAGEMAGICK_DATA
].count
== 1;
7453 /* The GIF library also defines DrawRectangle, but its never used in Emacs.
7454 Therefore rename the function so it doesnt collide with ImageMagick. */
7455 #define DrawRectangle DrawRectangleGif
7456 #include <wand/MagickWand.h>
7458 /* imagemagick_load_image is a helper function for imagemagick_load,
7459 which does the actual loading given contents and size, apart from
7460 frame and image structures, passed from imagemagick_load.
7462 Uses librimagemagick to do most of the image processing.
7464 non-zero when successful.
7468 imagemagick_load_image (/* Pointer to emacs frame structure. */
7470 /* Pointer to emacs image structure. */
7472 /* String containing the IMAGEMAGICK data to
7474 unsigned char *contents
,
7475 /* Size of data in bytes. */
7477 /* Filename, either pass filename or
7479 unsigned char *filename
)
7481 unsigned long width
;
7482 unsigned long height
;
7488 Lisp_Object specified_bg
;
7493 MagickWand
*image_wand
;
7494 MagickWand
*ping_wand
;
7495 PixelIterator
*iterator
;
7497 MagickPixelPacket pixel
;
7500 Lisp_Object crop
, geometry
;
7502 int desired_width
, desired_height
;
7504 int imagemagick_rendermethod
;
7506 ImageInfo
*image_info
;
7507 ExceptionInfo
*exception
;
7511 /* Handle image index for image types who can contain more than one
7512 image. Interface :index is same as for GIF. First we "ping" the
7513 image to see how many sub-images it contains. Pinging is faster
7514 than loading the image to find out things about it. */
7516 /* `MagickWandGenesis' initializes the imagemagick environment. */
7517 MagickWandGenesis ();
7518 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
7519 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
7520 ping_wand
= NewMagickWand ();
7521 MagickSetResolution (ping_wand
, 2, 2);
7522 if (filename
!= NULL
)
7524 status
= MagickPingImage (ping_wand
, filename
);
7528 status
= MagickPingImageBlob (ping_wand
, contents
, size
);
7531 if (ino
>= MagickGetNumberImages (ping_wand
))
7533 image_error ("Invalid image number `%s' in image `%s'",
7535 DestroyMagickWand (ping_wand
);
7539 if (MagickGetNumberImages(ping_wand
) > 1)
7540 img
->data
.lisp_val
=
7542 Fcons (make_number (MagickGetNumberImages (ping_wand
)),
7543 img
->data
.lisp_val
));
7545 DestroyMagickWand (ping_wand
);
7547 /* Now, after pinging, we know how many images are inside the
7548 file. If its not a bundle, just one. */
7550 if (filename
!= NULL
)
7552 image_info
= CloneImageInfo ((ImageInfo
*) NULL
);
7553 (void) strcpy (image_info
->filename
, filename
);
7554 image_info
->number_scenes
= 1;
7555 image_info
->scene
= ino
;
7556 exception
= AcquireExceptionInfo ();
7558 im_image
= ReadImage (image_info
, exception
);
7559 DestroyExceptionInfo (exception
);
7561 if (im_image
!= NULL
)
7563 image_wand
= NewMagickWandFromImage (im_image
);
7564 DestroyImage(im_image
);
7565 status
= MagickTrue
;
7568 status
= MagickFalse
;
7572 image_wand
= NewMagickWand ();
7573 status
= MagickReadImageBlob (image_wand
, contents
, size
);
7576 if (status
== MagickFalse
) goto imagemagick_error
;
7578 /* If width and/or height is set in the display spec assume we want
7579 to scale to those values. if either h or w is unspecified, the
7580 unspecified should be calculated from the specified to preserve
7583 value
= image_spec_value (img
->spec
, QCwidth
, NULL
);
7584 desired_width
= (INTEGERP (value
) ? XFASTINT (value
) : -1);
7585 value
= image_spec_value (img
->spec
, QCheight
, NULL
);
7586 desired_height
= (INTEGERP (value
) ? XFASTINT (value
) : -1);
7588 height
= MagickGetImageHeight (image_wand
);
7589 width
= MagickGetImageWidth (image_wand
);
7591 if(desired_width
!= -1 && desired_height
== -1)
7593 /* w known, calculate h. */
7594 desired_height
= (double) desired_width
/ width
* height
;
7596 if(desired_width
== -1 && desired_height
!= -1)
7598 /* h known, calculate w. */
7599 desired_width
= (double) desired_height
/ height
* width
;
7601 if(desired_width
!= -1 && desired_height
!= -1)
7603 status
= MagickScaleImage (image_wand
, desired_width
, desired_height
);
7604 if (status
== MagickFalse
)
7606 image_error ("Imagemagick scale failed", Qnil
, Qnil
);
7607 goto imagemagick_error
;
7612 /* crop behaves similar to image slicing in Emacs but is more memory
7614 crop
= image_spec_value (img
->spec
, QCcrop
, NULL
);
7616 if (CONSP (crop
) && INTEGERP (XCAR (crop
)))
7618 /* After some testing, it seems MagickCropImage is the fastest
7619 crop function in ImageMagick. This crop function seems to do
7620 less copying than the alternatives, but it still reads the
7621 entire image into memory before croping, which is aparently
7622 difficult to avoid when using imagemagick. */
7625 w
= XFASTINT (XCAR (crop
));
7627 if (CONSP (crop
) && INTEGERP (XCAR (crop
)))
7629 h
= XFASTINT (XCAR (crop
));
7631 if (CONSP (crop
) && INTEGERP (XCAR (crop
)))
7633 x
= XFASTINT (XCAR (crop
));
7635 if (CONSP (crop
) && INTEGERP (XCAR (crop
)))
7637 y
= XFASTINT (XCAR (crop
));
7638 MagickCropImage (image_wand
, w
, h
, x
, y
);
7644 /* Furthermore :rotation. we need background color and angle for
7647 TODO background handling for rotation specified_bg =
7648 image_spec_value (img->spec, QCbackground, NULL); if (!STRINGP
7650 value
= image_spec_value (img
->spec
, QCrotation
, NULL
);
7653 PixelWand
* background
= NewPixelWand ();
7654 PixelSetColor (background
, "#ffffff");/*TODO remove hardcode*/
7656 rotation
= extract_float (value
);
7658 status
= MagickRotateImage (image_wand
, background
, rotation
);
7659 DestroyPixelWand (background
);
7660 if (status
== MagickFalse
)
7662 image_error ("Imagemagick image rotate failed", Qnil
, Qnil
);
7663 goto imagemagick_error
;
7667 /* Finaly we are done manipulating the image, figure out resulting
7668 width, height, and then transfer ownerwship to Emacs. */
7669 height
= MagickGetImageHeight (image_wand
);
7670 width
= MagickGetImageWidth (image_wand
);
7672 if (! check_image_size (f
, width
, height
))
7674 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7675 goto imagemagick_error
;
7678 /* We can now get a valid pixel buffer from the imagemagick file, if all
7681 init_color_table ();
7682 imagemagick_rendermethod
= (INTEGERP (Vimagemagick_render_type
)
7683 ? XFASTINT (Vimagemagick_render_type
) : 0);
7684 if (imagemagick_rendermethod
== 0)
7686 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7687 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
7688 &ximg
, &img
->pixmap
))
7690 #ifdef COLOR_TABLE_SUPPORT
7691 free_color_table ();
7693 image_error("Imagemagick X bitmap allocation failure", Qnil
, Qnil
);
7694 goto imagemagick_error
;
7697 /* Copy imagegmagick image to x with primitive yet robust pixel
7698 pusher loop. This has been tested a lot with many different
7701 /* Copy pixels from the imagemagick image structure to the x image map. */
7702 iterator
= NewPixelIterator (image_wand
);
7703 if (iterator
== (PixelIterator
*) NULL
)
7705 #ifdef COLOR_TABLE_SUPPORT
7706 free_color_table ();
7708 x_destroy_x_image (ximg
);
7709 image_error ("Imagemagick pixel iterator creation failed",
7711 goto imagemagick_error
;
7714 for (y
= 0; y
< (long) MagickGetImageHeight (image_wand
); y
++)
7716 pixels
= PixelGetNextIteratorRow (iterator
, &width
);
7717 if (pixels
== (PixelWand
**) NULL
)
7719 for (x
= 0; x
< (long) width
; x
++)
7721 PixelGetMagickColor (pixels
[x
], &pixel
);
7722 XPutPixel (ximg
, x
, y
,
7723 lookup_rgb_color (f
,
7729 DestroyPixelIterator (iterator
);
7732 if (imagemagick_rendermethod
== 1)
7734 /* Magicexportimage is normaly faster than pixelpushing. This
7735 method is also well tested. Some aspects of this method are
7736 ad-hoc and needs to be more researched. */
7737 int imagedepth
= 24;/*MagickGetImageDepth(image_wand);*/
7738 char* exportdepth
= imagedepth
<= 8 ? "I" : "BGRP";/*"RGBP";*/
7739 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7740 if (!x_create_x_image_and_pixmap (f
, width
, height
, imagedepth
,
7741 &ximg
, &img
->pixmap
))
7743 #ifdef COLOR_TABLE_SUPPORT
7744 free_color_table ();
7746 image_error("Imagemagick X bitmap allocation failure", Qnil
, Qnil
);
7747 goto imagemagick_error
;
7751 /* Oddly, the below code doesnt seem to work:*/
7752 /* switch(ximg->bitmap_unit){ */
7754 /* pixelwidth=CharPixel; */
7757 /* pixelwidth=ShortPixel; */
7760 /* pixelwidth=LongPixel; */
7764 Here im just guessing the format of the bitmap.
7765 happens to work fine for:
7768 seems about 3 times as fast as pixel pushing(not carefully measured)
7770 pixelwidth
= CharPixel
;/*??? TODO figure out*/
7771 #ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
7772 MagickExportImagePixels (image_wand
,
7777 /*&(img->pixmap));*/
7780 image_error ("You dont have MagickExportImagePixels, upgrade ImageMagick!",
7786 #ifdef COLOR_TABLE_SUPPORT
7787 /* Remember colors allocated for this image. */
7788 img
->colors
= colors_in_color_table (&img
->ncolors
);
7789 free_color_table ();
7790 #endif /* COLOR_TABLE_SUPPORT */
7794 img
->height
= height
;
7796 /* Put the image into the pixmap, then free the X image and its
7798 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7799 x_destroy_x_image (ximg
);
7802 /* Final cleanup. image_wand should be the only resource left. */
7803 DestroyMagickWand (image_wand
);
7804 /* `MagickWandTerminus' terminates the imagemagick environment. */
7805 MagickWandTerminus ();
7810 DestroyMagickWand (image_wand
);
7811 MagickWandTerminus ();
7812 /* TODO more cleanup. */
7813 image_error ("Error parsing IMAGEMAGICK image `%s'", img
->spec
, Qnil
);
7818 /* Load IMAGEMAGICK image IMG for use on frame F. Value is non-zero if
7819 successful. this function will go into the imagemagick_type structure, and
7820 the prototype thus needs to be compatible with that structure. */
7823 imagemagick_load (struct frame
*f
,
7827 Lisp_Object file_name
;
7829 /* If IMG->spec specifies a file name, create a non-file spec from it. */
7830 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
7831 if (STRINGP (file_name
))
7835 file
= x_find_image_file (file_name
);
7836 if (!STRINGP (file
))
7838 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
7841 success_p
= imagemagick_load_image (f
, img
, 0, 0, SDATA (file
));
7843 /* Else its not a file, its a lisp object. Load the image from a
7844 lisp object rather than a file. */
7849 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7850 if (!STRINGP (data
))
7852 image_error ("Invalid image data `%s'", data
, Qnil
);
7855 success_p
= imagemagick_load_image (f
, img
, SDATA (data
),
7856 SBYTES (data
), NULL
);
7862 /* Structure describing the image type `imagemagick'. Its the same
7863 type of structure defined for all image formats, handled by Emacs
7864 image functions. See struct image_type in dispextern.h. */
7866 static struct image_type imagemagick_type
=
7868 /* An identifier showing that this is an image structure for the
7869 IMAGEMAGICK format. */
7871 /* Handle to a function that can be used to identify a IMAGEMAGICK
7873 imagemagick_image_p
,
7874 /* Handle to function used to load a IMAGEMAGICK file. */
7876 /* Handle to function to free resources for IMAGEMAGICK. */
7877 imagemagick_clear_image
,
7878 /* An internal field to link to the next image type in a list of
7879 image types, will be filled in when registering the format. */
7886 DEFUN ("imagemagick-types", Fimagemagick_types
, Simagemagick_types
, 0, 0, 0,
7887 doc
: /* Return image file types supported by ImageMagick.
7888 Since ImageMagick recognizes a lot of file-types that clash with Emacs,
7889 such as .c, we want to be able to alter the list at the lisp level. */)
7892 Lisp_Object typelist
= Qnil
;
7895 char **imtypes
= GetMagickList ("*", &numf
, &ex
);
7897 Lisp_Object Qimagemagicktype
;
7898 for (i
= 0; i
< numf
; i
++)
7900 Qimagemagicktype
= intern (imtypes
[i
]);
7901 typelist
= Fcons (Qimagemagicktype
, typelist
);
7906 #endif /* defined (HAVE_IMAGEMAGICK) */
7910 /***********************************************************************
7912 ***********************************************************************/
7914 #if defined (HAVE_RSVG)
7916 /* Function prototypes. */
7918 static int svg_image_p (Lisp_Object object
);
7919 static int svg_load (struct frame
*f
, struct image
*img
);
7921 static int svg_load_image (struct frame
*, struct image
*,
7922 unsigned char *, unsigned int);
7924 /* The symbol `svg' identifying images of this type. */
7928 /* Indices of image specification fields in svg_format, below. */
7930 enum svg_keyword_index
7945 /* Vector of image_keyword structures describing the format
7946 of valid user-defined image specifications. */
7948 static const struct image_keyword svg_format
[SVG_LAST
] =
7950 {":type", IMAGE_SYMBOL_VALUE
, 1},
7951 {":data", IMAGE_STRING_VALUE
, 0},
7952 {":file", IMAGE_STRING_VALUE
, 0},
7953 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7954 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
7955 {":relief", IMAGE_INTEGER_VALUE
, 0},
7956 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7957 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7958 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7959 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7962 /* Structure describing the image type `svg'. Its the same type of
7963 structure defined for all image formats, handled by emacs image
7964 functions. See struct image_type in dispextern.h. */
7966 static struct image_type svg_type
=
7968 /* An identifier showing that this is an image structure for the SVG format. */
7970 /* Handle to a function that can be used to identify a SVG file. */
7972 /* Handle to function used to load a SVG file. */
7974 /* Handle to function to free sresources for SVG. */
7976 /* An internal field to link to the next image type in a list of
7977 image types, will be filled in when registering the format. */
7982 /* Return non-zero if OBJECT is a valid SVG image specification. Do
7983 this by calling parse_image_spec and supplying the keywords that
7984 identify the SVG format. */
7987 svg_image_p (Lisp_Object object
)
7989 struct image_keyword fmt
[SVG_LAST
];
7990 memcpy (fmt
, svg_format
, sizeof fmt
);
7992 if (!parse_image_spec (object
, fmt
, SVG_LAST
, Qsvg
))
7995 /* Must specify either the :data or :file keyword. */
7996 return fmt
[SVG_FILE
].count
+ fmt
[SVG_DATA
].count
== 1;
7999 #include <librsvg/rsvg.h>
8003 /* SVG library functions. */
8004 DEF_IMGLIB_FN (RsvgHandle
*, rsvg_handle_new
);
8005 DEF_IMGLIB_FN (void, rsvg_handle_get_dimensions
);
8006 DEF_IMGLIB_FN (gboolean
, rsvg_handle_write
);
8007 DEF_IMGLIB_FN (gboolean
, rsvg_handle_close
);
8008 DEF_IMGLIB_FN (GdkPixbuf
*, rsvg_handle_get_pixbuf
);
8009 DEF_IMGLIB_FN (void, rsvg_handle_free
);
8011 DEF_IMGLIB_FN (int, gdk_pixbuf_get_width
);
8012 DEF_IMGLIB_FN (int, gdk_pixbuf_get_height
);
8013 DEF_IMGLIB_FN (guchar
*, gdk_pixbuf_get_pixels
);
8014 DEF_IMGLIB_FN (int, gdk_pixbuf_get_rowstride
);
8015 DEF_IMGLIB_FN (GdkColorspace
, gdk_pixbuf_get_colorspace
);
8016 DEF_IMGLIB_FN (int, gdk_pixbuf_get_n_channels
);
8017 DEF_IMGLIB_FN (gboolean
, gdk_pixbuf_get_has_alpha
);
8018 DEF_IMGLIB_FN (int, gdk_pixbuf_get_bits_per_sample
);
8020 DEF_IMGLIB_FN (void, g_type_init
);
8021 DEF_IMGLIB_FN (void, g_object_unref
);
8022 DEF_IMGLIB_FN (void, g_error_free
);
8024 Lisp_Object Qgdk_pixbuf
, Qglib
, Qgobject
;
8027 init_svg_functions (Lisp_Object libraries
)
8029 HMODULE library
, gdklib
, glib
, gobject
;
8031 if (!(glib
= w32_delayed_load (libraries
, Qglib
))
8032 || !(gobject
= w32_delayed_load (libraries
, Qgobject
))
8033 || !(gdklib
= w32_delayed_load (libraries
, Qgdk_pixbuf
))
8034 || !(library
= w32_delayed_load (libraries
, Qsvg
)))
8037 LOAD_IMGLIB_FN (library
, rsvg_handle_new
);
8038 LOAD_IMGLIB_FN (library
, rsvg_handle_get_dimensions
);
8039 LOAD_IMGLIB_FN (library
, rsvg_handle_write
);
8040 LOAD_IMGLIB_FN (library
, rsvg_handle_close
);
8041 LOAD_IMGLIB_FN (library
, rsvg_handle_get_pixbuf
);
8042 LOAD_IMGLIB_FN (library
, rsvg_handle_free
);
8044 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_width
);
8045 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_height
);
8046 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_pixels
);
8047 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_rowstride
);
8048 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_colorspace
);
8049 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_n_channels
);
8050 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_has_alpha
);
8051 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_bits_per_sample
);
8053 LOAD_IMGLIB_FN (gobject
, g_type_init
);
8054 LOAD_IMGLIB_FN (gobject
, g_object_unref
);
8055 LOAD_IMGLIB_FN (glib
, g_error_free
);
8061 /* The following aliases for library functions allow dynamic loading
8062 to be used on some platforms. */
8063 #define fn_rsvg_handle_new rsvg_handle_new
8064 #define fn_rsvg_handle_get_dimensions rsvg_handle_get_dimensions
8065 #define fn_rsvg_handle_write rsvg_handle_write
8066 #define fn_rsvg_handle_close rsvg_handle_close
8067 #define fn_rsvg_handle_get_pixbuf rsvg_handle_get_pixbuf
8068 #define fn_rsvg_handle_free rsvg_handle_free
8070 #define fn_gdk_pixbuf_get_width gdk_pixbuf_get_width
8071 #define fn_gdk_pixbuf_get_height gdk_pixbuf_get_height
8072 #define fn_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels
8073 #define fn_gdk_pixbuf_get_rowstride gdk_pixbuf_get_rowstride
8074 #define fn_gdk_pixbuf_get_colorspace gdk_pixbuf_get_colorspace
8075 #define fn_gdk_pixbuf_get_n_channels gdk_pixbuf_get_n_channels
8076 #define fn_gdk_pixbuf_get_has_alpha gdk_pixbuf_get_has_alpha
8077 #define fn_gdk_pixbuf_get_bits_per_sample gdk_pixbuf_get_bits_per_sample
8079 #define fn_g_type_init g_type_init
8080 #define fn_g_object_unref g_object_unref
8081 #define fn_g_error_free g_error_free
8082 #endif /* !HAVE_NTGUI */
8084 /* Load SVG image IMG for use on frame F. Value is non-zero if
8085 successful. this function will go into the svg_type structure, and
8086 the prototype thus needs to be compatible with that structure. */
8089 svg_load (struct frame
*f
, struct image
*img
)
8092 Lisp_Object file_name
;
8094 /* If IMG->spec specifies a file name, create a non-file spec from it. */
8095 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
8096 if (STRINGP (file_name
))
8099 unsigned char *contents
;
8102 file
= x_find_image_file (file_name
);
8103 if (!STRINGP (file
))
8105 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
8109 /* Read the entire file into memory. */
8110 contents
= slurp_file (SDATA (file
), &size
);
8111 if (contents
== NULL
)
8113 image_error ("Error loading SVG image `%s'", img
->spec
, Qnil
);
8116 /* If the file was slurped into memory properly, parse it. */
8117 success_p
= svg_load_image (f
, img
, contents
, size
);
8120 /* Else its not a file, its a lisp object. Load the image from a
8121 lisp object rather than a file. */
8126 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8127 if (!STRINGP (data
))
8129 image_error ("Invalid image data `%s'", data
, Qnil
);
8132 success_p
= svg_load_image (f
, img
, SDATA (data
), SBYTES (data
));
8138 /* svg_load_image is a helper function for svg_load, which does the
8139 actual loading given contents and size, apart from frame and image
8140 structures, passed from svg_load.
8142 Uses librsvg to do most of the image processing.
8144 Returns non-zero when successful. */
8146 svg_load_image (struct frame
*f
, /* Pointer to emacs frame structure. */
8147 struct image
*img
, /* Pointer to emacs image structure. */
8148 unsigned char *contents
, /* String containing the SVG XML data to be parsed. */
8149 unsigned int size
) /* Size of data in bytes. */
8151 RsvgHandle
*rsvg_handle
;
8152 RsvgDimensionData dimension_data
;
8153 GError
*error
= NULL
;
8157 const guint8
*pixels
;
8160 Lisp_Object specified_bg
;
8165 /* g_type_init is a glib function that must be called prior to using
8166 gnome type library functions. */
8168 /* Make a handle to a new rsvg object. */
8169 rsvg_handle
= fn_rsvg_handle_new ();
8171 /* Parse the contents argument and fill in the rsvg_handle. */
8172 fn_rsvg_handle_write (rsvg_handle
, contents
, size
, &error
);
8173 if (error
) goto rsvg_error
;
8175 /* The parsing is complete, rsvg_handle is ready to used, close it
8176 for further writes. */
8177 fn_rsvg_handle_close (rsvg_handle
, &error
);
8178 if (error
) goto rsvg_error
;
8180 fn_rsvg_handle_get_dimensions (rsvg_handle
, &dimension_data
);
8181 if (! check_image_size (f
, dimension_data
.width
, dimension_data
.height
))
8183 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
8187 /* We can now get a valid pixel buffer from the svg file, if all
8189 pixbuf
= fn_rsvg_handle_get_pixbuf (rsvg_handle
);
8190 if (!pixbuf
) goto rsvg_error
;
8191 fn_g_object_unref (rsvg_handle
);
8193 /* Extract some meta data from the svg handle. */
8194 width
= fn_gdk_pixbuf_get_width (pixbuf
);
8195 height
= fn_gdk_pixbuf_get_height (pixbuf
);
8196 pixels
= fn_gdk_pixbuf_get_pixels (pixbuf
);
8197 rowstride
= fn_gdk_pixbuf_get_rowstride (pixbuf
);
8199 /* Validate the svg meta data. */
8200 eassert (fn_gdk_pixbuf_get_colorspace (pixbuf
) == GDK_COLORSPACE_RGB
);
8201 eassert (fn_gdk_pixbuf_get_n_channels (pixbuf
) == 4);
8202 eassert (fn_gdk_pixbuf_get_has_alpha (pixbuf
));
8203 eassert (fn_gdk_pixbuf_get_bits_per_sample (pixbuf
) == 8);
8205 /* Try to create a x pixmap to hold the svg pixmap. */
8206 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8208 fn_g_object_unref (pixbuf
);
8212 init_color_table ();
8214 /* Handle alpha channel by combining the image with a background
8216 specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
8217 if (!STRINGP (specified_bg
)
8218 || !x_defined_color (f
, SDATA (specified_bg
), &background
, 0))
8221 background
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
8222 x_query_color (f
, &background
);
8224 ns_query_color (FRAME_BACKGROUND_COLOR (f
), &background
, 1);
8228 /* SVG pixmaps specify transparency in the last byte, so right
8229 shift 8 bits to get rid of it, since emacs doesn't support
8231 background
.red
>>= 8;
8232 background
.green
>>= 8;
8233 background
.blue
>>= 8;
8235 /* This loop handles opacity values, since Emacs assumes
8236 non-transparent images. Each pixel must be "flattened" by
8237 calculating the resulting color, given the transparency of the
8238 pixel, and the image background color. */
8239 for (y
= 0; y
< height
; ++y
)
8241 for (x
= 0; x
< width
; ++x
)
8251 opacity
= *pixels
++;
8253 red
= ((red
* opacity
)
8254 + (background
.red
* ((1 << 8) - opacity
)));
8255 green
= ((green
* opacity
)
8256 + (background
.green
* ((1 << 8) - opacity
)));
8257 blue
= ((blue
* opacity
)
8258 + (background
.blue
* ((1 << 8) - opacity
)));
8260 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, red
, green
, blue
));
8263 pixels
+= rowstride
- 4 * width
;
8266 #ifdef COLOR_TABLE_SUPPORT
8267 /* Remember colors allocated for this image. */
8268 img
->colors
= colors_in_color_table (&img
->ncolors
);
8269 free_color_table ();
8270 #endif /* COLOR_TABLE_SUPPORT */
8272 fn_g_object_unref (pixbuf
);
8275 img
->height
= height
;
8277 /* Maybe fill in the background field while we have ximg handy.
8278 Casting avoids a GCC warning. */
8279 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
8281 /* Put the image into the pixmap, then free the X image and its
8283 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8284 x_destroy_x_image (ximg
);
8289 fn_g_object_unref (rsvg_handle
);
8290 /* FIXME: Use error->message so the user knows what is the actual
8291 problem with the image. */
8292 image_error ("Error parsing SVG image `%s'", img
->spec
, Qnil
);
8293 fn_g_error_free (error
);
8297 #endif /* defined (HAVE_RSVG) */
8302 /***********************************************************************
8304 ***********************************************************************/
8306 #ifdef HAVE_X_WINDOWS
8307 #define HAVE_GHOSTSCRIPT 1
8308 #endif /* HAVE_X_WINDOWS */
8310 #ifdef HAVE_GHOSTSCRIPT
8312 static int gs_image_p (Lisp_Object object
);
8313 static int gs_load (struct frame
*f
, struct image
*img
);
8314 static void gs_clear_image (struct frame
*f
, struct image
*img
);
8316 /* Keyword symbols. */
8318 Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
8320 /* Indices of image specification fields in gs_format, below. */
8322 enum gs_keyword_index
8340 /* Vector of image_keyword structures describing the format
8341 of valid user-defined image specifications. */
8343 static const struct image_keyword gs_format
[GS_LAST
] =
8345 {":type", IMAGE_SYMBOL_VALUE
, 1},
8346 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8347 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8348 {":file", IMAGE_STRING_VALUE
, 1},
8349 {":loader", IMAGE_FUNCTION_VALUE
, 0},
8350 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
8351 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8352 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR
, 0},
8353 {":relief", IMAGE_INTEGER_VALUE
, 0},
8354 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8355 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8356 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8357 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8360 /* Structure describing the image type `ghostscript'. */
8362 static struct image_type gs_type
=
8372 /* Free X resources of Ghostscript image IMG which is used on frame F. */
8375 gs_clear_image (struct frame
*f
, struct image
*img
)
8377 /* IMG->data.ptr_val may contain a recorded colormap. */
8378 xfree (img
->data
.ptr_val
);
8379 x_clear_image (f
, img
);
8383 /* Return non-zero if OBJECT is a valid Ghostscript image
8387 gs_image_p (Lisp_Object object
)
8389 struct image_keyword fmt
[GS_LAST
];
8393 memcpy (fmt
, gs_format
, sizeof fmt
);
8395 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
8398 /* Bounding box must be a list or vector containing 4 integers. */
8399 tem
= fmt
[GS_BOUNDING_BOX
].value
;
8402 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
8403 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
8408 else if (VECTORP (tem
))
8410 if (XVECTOR (tem
)->size
!= 4)
8412 for (i
= 0; i
< 4; ++i
)
8413 if (!INTEGERP (XVECTOR (tem
)->contents
[i
]))
8423 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
8427 gs_load (struct frame
*f
, struct image
*img
)
8430 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
8432 double in_width
, in_height
;
8433 Lisp_Object pixel_colors
= Qnil
;
8435 /* Compute pixel size of pixmap needed from the given size in the
8436 image specification. Sizes in the specification are in pt. 1 pt
8437 = 1/72 in, xdpi and ydpi are stored in the frame's X display
8439 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
8440 in_width
= INTEGERP (pt_width
) ? XFASTINT (pt_width
) / 72.0 : 0;
8441 img
->width
= in_width
* FRAME_X_DISPLAY_INFO (f
)->resx
;
8442 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
8443 in_height
= INTEGERP (pt_height
) ? XFASTINT (pt_height
) / 72.0 : 0;
8444 img
->height
= in_height
* FRAME_X_DISPLAY_INFO (f
)->resy
;
8446 if (!check_image_size (f
, img
->width
, img
->height
))
8448 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
8452 /* Create the pixmap. */
8453 xassert (img
->pixmap
== NO_PIXMAP
);
8455 /* Only W32 version did BLOCK_INPUT here. ++kfs */
8457 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8458 img
->width
, img
->height
,
8459 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
8464 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
8468 /* Call the loader to fill the pixmap. It returns a process object
8469 if successful. We do not record_unwind_protect here because
8470 other places in redisplay like calling window scroll functions
8471 don't either. Let the Lisp loader use `unwind-protect' instead. */
8472 sprintf (buffer
, "%lu %lu",
8473 (unsigned long) FRAME_X_WINDOW (f
),
8474 (unsigned long) img
->pixmap
);
8475 window_and_pixmap_id
= build_string (buffer
);
8477 sprintf (buffer
, "%lu %lu",
8478 FRAME_FOREGROUND_PIXEL (f
),
8479 FRAME_BACKGROUND_PIXEL (f
));
8480 pixel_colors
= build_string (buffer
);
8482 XSETFRAME (frame
, f
);
8483 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
8485 loader
= intern ("gs-load-image");
8487 img
->data
.lisp_val
= call6 (loader
, frame
, img
->spec
,
8488 make_number (img
->width
),
8489 make_number (img
->height
),
8490 window_and_pixmap_id
,
8492 return PROCESSP (img
->data
.lisp_val
);
8496 /* Kill the Ghostscript process that was started to fill PIXMAP on
8497 frame F. Called from XTread_socket when receiving an event
8498 telling Emacs that Ghostscript has finished drawing. */
8501 x_kill_gs_process (Pixmap pixmap
, struct frame
*f
)
8503 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
8507 /* Find the image containing PIXMAP. */
8508 for (i
= 0; i
< c
->used
; ++i
)
8509 if (c
->images
[i
]->pixmap
== pixmap
)
8512 /* Should someone in between have cleared the image cache, for
8513 instance, give up. */
8517 /* Kill the GS process. We should have found PIXMAP in the image
8518 cache and its image should contain a process object. */
8520 xassert (PROCESSP (img
->data
.lisp_val
));
8521 Fkill_process (img
->data
.lisp_val
, Qnil
);
8522 img
->data
.lisp_val
= Qnil
;
8524 #if defined (HAVE_X_WINDOWS)
8526 /* On displays with a mutable colormap, figure out the colors
8527 allocated for the image by looking at the pixels of an XImage for
8529 class = FRAME_X_VISUAL (f
)->class;
8530 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
8536 /* Try to get an XImage for img->pixmep. */
8537 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
8538 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
8543 /* Initialize the color table. */
8544 init_color_table ();
8546 /* For each pixel of the image, look its color up in the
8547 color table. After having done so, the color table will
8548 contain an entry for each color used by the image. */
8549 for (y
= 0; y
< img
->height
; ++y
)
8550 for (x
= 0; x
< img
->width
; ++x
)
8552 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
8553 lookup_pixel_color (f
, pixel
);
8556 /* Record colors in the image. Free color table and XImage. */
8557 #ifdef COLOR_TABLE_SUPPORT
8558 img
->colors
= colors_in_color_table (&img
->ncolors
);
8559 free_color_table ();
8561 XDestroyImage (ximg
);
8563 #if 0 /* This doesn't seem to be the case. If we free the colors
8564 here, we get a BadAccess later in x_clear_image when
8565 freeing the colors. */
8566 /* We have allocated colors once, but Ghostscript has also
8567 allocated colors on behalf of us. So, to get the
8568 reference counts right, free them once. */
8570 x_free_colors (f
, img
->colors
, img
->ncolors
);
8574 image_error ("Cannot get X image of `%s'; colors will not be freed",
8579 #endif /* HAVE_X_WINDOWS */
8581 /* Now that we have the pixmap, compute mask and transform the
8582 image if requested. */
8584 postprocess_image (f
, img
);
8588 #endif /* HAVE_GHOSTSCRIPT */
8591 /***********************************************************************
8593 ***********************************************************************/
8597 DEFUN ("imagep", Fimagep
, Simagep
, 1, 1, 0,
8598 doc
: /* Value is non-nil if SPEC is a valid image specification. */)
8601 return valid_image_p (spec
) ? Qt
: Qnil
;
8605 DEFUN ("lookup-image", Flookup_image
, Slookup_image
, 1, 1, 0, "")
8610 if (valid_image_p (spec
))
8611 id
= lookup_image (SELECTED_FRAME (), spec
);
8614 return make_number (id
);
8617 #endif /* GLYPH_DEBUG != 0 */
8620 /***********************************************************************
8622 ***********************************************************************/
8625 /* Image types that rely on external libraries are loaded dynamically
8626 if the library is available. */
8627 #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8628 define_image_type (image_type, init_lib_fn (libraries))
8630 #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8631 define_image_type (image_type, 1)
8632 #endif /* HAVE_NTGUI */
8634 DEFUN ("init-image-library", Finit_image_library
, Sinit_image_library
, 2, 2, 0,
8635 doc
: /* Initialize image library implementing image type TYPE.
8636 Return non-nil if TYPE is a supported image type.
8638 Image types pbm and xbm are prebuilt; other types are loaded here.
8639 Libraries to load are specified in alist LIBRARIES (usually, the value
8640 of `dynamic-library-alist', which see). */)
8641 (Lisp_Object type
, Lisp_Object libraries
)
8645 /* Don't try to reload the library. */
8646 tested
= Fassq (type
, Vimage_type_cache
);
8648 return XCDR (tested
);
8650 #if defined (HAVE_XPM) || defined (HAVE_NS)
8651 if (EQ (type
, Qxpm
))
8652 return CHECK_LIB_AVAILABLE (&xpm_type
, init_xpm_functions
, libraries
);
8655 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8656 if (EQ (type
, Qjpeg
))
8657 return CHECK_LIB_AVAILABLE (&jpeg_type
, init_jpeg_functions
, libraries
);
8660 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8661 if (EQ (type
, Qtiff
))
8662 return CHECK_LIB_AVAILABLE (&tiff_type
, init_tiff_functions
, libraries
);
8665 #if defined (HAVE_GIF) || defined (HAVE_NS)
8666 if (EQ (type
, Qgif
))
8667 return CHECK_LIB_AVAILABLE (&gif_type
, init_gif_functions
, libraries
);
8670 #if defined (HAVE_PNG) || defined (HAVE_NS)
8671 if (EQ (type
, Qpng
))
8672 return CHECK_LIB_AVAILABLE (&png_type
, init_png_functions
, libraries
);
8675 #if defined (HAVE_RSVG)
8676 if (EQ (type
, Qsvg
))
8677 return CHECK_LIB_AVAILABLE (&svg_type
, init_svg_functions
, libraries
);
8680 #if defined (HAVE_IMAGEMAGICK)
8681 if (EQ (type
, Qimagemagick
))
8683 return CHECK_LIB_AVAILABLE (&imagemagick_type
, init_imagemagick_functions
,
8688 #ifdef HAVE_GHOSTSCRIPT
8689 if (EQ (type
, Qpostscript
))
8690 return CHECK_LIB_AVAILABLE (&gs_type
, init_gs_functions
, libraries
);
8693 /* If the type is not recognized, avoid testing it ever again. */
8694 CACHE_IMAGE_TYPE (type
, Qnil
);
8699 syms_of_image (void)
8701 /* Initialize this only once, since that's what we do with Vimage_types
8702 and they are supposed to be in sync. Initializing here gives correct
8703 operation on GNU/Linux of calling dump-emacs after loading some images. */
8706 /* Must be defined now becase we're going to update it below, while
8707 defining the supported image types. */
8708 DEFVAR_LISP ("image-types", Vimage_types
,
8709 doc
: /* List of potentially supported image types.
8710 Each element of the list is a symbol for an image type, like 'jpeg or 'png.
8711 To check whether it is really supported, use `image-type-available-p'. */);
8712 Vimage_types
= Qnil
;
8714 DEFVAR_LISP ("max-image-size", Vmax_image_size
,
8715 doc
: /* Maximum size of images.
8716 Emacs will not load an image into memory if its pixel width or
8717 pixel height exceeds this limit.
8719 If the value is an integer, it directly specifies the maximum
8720 image height and width, measured in pixels. If it is a floating
8721 point number, it specifies the maximum image height and width
8722 as a ratio to the frame height and width. If the value is
8723 non-numeric, there is no explicit limit on the size of images. */);
8724 Vmax_image_size
= make_float (MAX_IMAGE_SIZE
);
8726 Vimage_type_cache
= Qnil
;
8727 staticpro (&Vimage_type_cache
);
8729 Qpbm
= intern_c_string ("pbm");
8731 ADD_IMAGE_TYPE (Qpbm
);
8733 Qxbm
= intern_c_string ("xbm");
8735 ADD_IMAGE_TYPE (Qxbm
);
8737 define_image_type (&xbm_type
, 1);
8738 define_image_type (&pbm_type
, 1);
8740 Qcount
= intern_c_string ("count");
8741 staticpro (&Qcount
);
8742 Qextension_data
= intern_c_string ("extension-data");
8743 staticpro (&Qextension_data
);
8745 QCascent
= intern_c_string (":ascent");
8746 staticpro (&QCascent
);
8747 QCmargin
= intern_c_string (":margin");
8748 staticpro (&QCmargin
);
8749 QCrelief
= intern_c_string (":relief");
8750 staticpro (&QCrelief
);
8751 QCconversion
= intern_c_string (":conversion");
8752 staticpro (&QCconversion
);
8753 QCcolor_symbols
= intern_c_string (":color-symbols");
8754 staticpro (&QCcolor_symbols
);
8755 QCheuristic_mask
= intern_c_string (":heuristic-mask");
8756 staticpro (&QCheuristic_mask
);
8757 QCindex
= intern_c_string (":index");
8758 staticpro (&QCindex
);
8759 QCgeometry
= intern_c_string (":geometry");
8760 staticpro (&QCgeometry
);
8761 QCcrop
= intern_c_string (":crop");
8762 staticpro (&QCcrop
);
8763 QCrotation
= intern_c_string (":rotation");
8764 staticpro (&QCrotation
);
8765 QCmatrix
= intern_c_string (":matrix");
8766 staticpro (&QCmatrix
);
8767 QCcolor_adjustment
= intern_c_string (":color-adjustment");
8768 staticpro (&QCcolor_adjustment
);
8769 QCmask
= intern_c_string (":mask");
8770 staticpro (&QCmask
);
8772 Qlaplace
= intern_c_string ("laplace");
8773 staticpro (&Qlaplace
);
8774 Qemboss
= intern_c_string ("emboss");
8775 staticpro (&Qemboss
);
8776 Qedge_detection
= intern_c_string ("edge-detection");
8777 staticpro (&Qedge_detection
);
8778 Qheuristic
= intern_c_string ("heuristic");
8779 staticpro (&Qheuristic
);
8781 Qpostscript
= intern_c_string ("postscript");
8782 staticpro (&Qpostscript
);
8783 #ifdef HAVE_GHOSTSCRIPT
8784 ADD_IMAGE_TYPE (Qpostscript
);
8785 QCloader
= intern_c_string (":loader");
8786 staticpro (&QCloader
);
8787 QCbounding_box
= intern_c_string (":bounding-box");
8788 staticpro (&QCbounding_box
);
8789 QCpt_width
= intern_c_string (":pt-width");
8790 staticpro (&QCpt_width
);
8791 QCpt_height
= intern_c_string (":pt-height");
8792 staticpro (&QCpt_height
);
8793 #endif /* HAVE_GHOSTSCRIPT */
8796 Qlibpng_version
= intern_c_string ("libpng-version");
8797 staticpro (&Qlibpng_version
);
8798 Fset (Qlibpng_version
,
8800 make_number (PNG_LIBPNG_VER
)
8807 #if defined (HAVE_XPM) || defined (HAVE_NS)
8808 Qxpm
= intern_c_string ("xpm");
8810 ADD_IMAGE_TYPE (Qxpm
);
8813 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8814 Qjpeg
= intern_c_string ("jpeg");
8816 ADD_IMAGE_TYPE (Qjpeg
);
8819 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8820 Qtiff
= intern_c_string ("tiff");
8822 ADD_IMAGE_TYPE (Qtiff
);
8825 #if defined (HAVE_GIF) || defined (HAVE_NS)
8826 Qgif
= intern_c_string ("gif");
8828 ADD_IMAGE_TYPE (Qgif
);
8831 #if defined (HAVE_PNG) || defined (HAVE_NS)
8832 Qpng
= intern_c_string ("png");
8834 ADD_IMAGE_TYPE (Qpng
);
8837 #if defined (HAVE_IMAGEMAGICK)
8838 Qimagemagick
= intern_c_string ("imagemagick");
8839 staticpro (&Qimagemagick
);
8840 ADD_IMAGE_TYPE (Qimagemagick
);
8843 #if defined (HAVE_RSVG)
8844 Qsvg
= intern_c_string ("svg");
8846 ADD_IMAGE_TYPE (Qsvg
);
8848 /* Other libraries used directly by svg code. */
8849 Qgdk_pixbuf
= intern_c_string ("gdk-pixbuf");
8850 staticpro (&Qgdk_pixbuf
);
8851 Qglib
= intern_c_string ("glib");
8853 Qgobject
= intern_c_string ("gobject");
8854 staticpro (&Qgobject
);
8855 #endif /* HAVE_NTGUI */
8856 #endif /* HAVE_RSVG */
8858 defsubr (&Sinit_image_library
);
8859 #ifdef HAVE_IMAGEMAGICK
8860 defsubr (&Simagemagick_types
);
8862 defsubr (&Sclear_image_cache
);
8863 defsubr (&Simage_flush
);
8864 defsubr (&Simage_size
);
8865 defsubr (&Simage_mask_p
);
8866 defsubr (&Simage_metadata
);
8870 defsubr (&Slookup_image
);
8873 DEFVAR_BOOL ("cross-disabled-images", cross_disabled_images
,
8874 doc
: /* Non-nil means always draw a cross over disabled images.
8875 Disabled images are those having a `:conversion disabled' property.
8876 A cross is always drawn on black & white displays. */);
8877 cross_disabled_images
= 0;
8879 DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path
,
8880 doc
: /* List of directories to search for window system bitmap files. */);
8881 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
8883 DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay
,
8884 doc
: /* Maximum time after which images are removed from the cache.
8885 When an image has not been displayed this many seconds, Emacs
8886 automatically removes it from the image cache. If the cache contains
8887 a large number of images, the actual eviction time may be shorter.
8888 The value can also be nil, meaning the cache is never cleared.
8890 The function `clear-image-cache' disregards this variable. */);
8891 Vimage_cache_eviction_delay
= make_number (300);
8892 #ifdef HAVE_IMAGEMAGICK
8893 DEFVAR_LISP ("imagemagick-render-type", Vimagemagick_render_type
,
8894 doc
: /* Choose between ImageMagick render methods. */);