1 /* Functions for image support on window system.
3 Copyright (C) 1989, 1992-2012 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
27 #if defined HAVE_LIBPNG_PNG_H
28 # include <libpng/png.h>
36 /* This makes the fields of a Display accessible, in Xlib header files. */
38 #define XLIB_ILLEGAL_ACCESS
43 #include "dispextern.h"
44 #include "blockinput.h"
47 #include "character.h"
49 #include "termhooks.h"
54 #include <sys/types.h>
57 #define COLOR_TABLE_SUPPORT 1
59 typedef struct x_bitmap_record Bitmap_Record
;
60 #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
61 #define NO_PIXMAP None
63 #define RGB_PIXEL_COLOR unsigned long
65 #define PIX_MASK_RETAIN 0
66 #define PIX_MASK_DRAW 1
67 #endif /* HAVE_X_WINDOWS */
74 /* W32_TODO : Color tables on W32. */
75 #undef COLOR_TABLE_SUPPORT
77 typedef struct w32_bitmap_record Bitmap_Record
;
78 #define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y)
81 #define RGB_PIXEL_COLOR COLORREF
83 #define PIX_MASK_RETAIN 0
84 #define PIX_MASK_DRAW 1
86 #define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual
87 #define x_defined_color w32_defined_color
88 #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
90 /* Functions from w32term.c that depend on XColor (so can't go in w32term.h
91 without modifying lots of files). */
92 extern void x_query_colors (struct frame
*f
, XColor
*colors
, int ncolors
);
93 extern void x_query_color (struct frame
*f
, XColor
*color
);
95 /* Version of libpng that we were compiled with, or -1 if no PNG
96 support was compiled in. This is tested by w32-win.el to correctly
97 set up the alist used to search for PNG libraries. */
98 Lisp_Object Qlibpng_version
;
99 #endif /* HAVE_NTGUI */
103 #include <sys/types.h>
104 #include <sys/stat.h>
106 #undef COLOR_TABLE_SUPPORT
108 typedef struct ns_bitmap_record Bitmap_Record
;
110 #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
113 #define RGB_PIXEL_COLOR unsigned long
116 #define PIX_MASK_RETAIN 0
117 #define PIX_MASK_DRAW 1
119 #define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO (f)->visual
120 #define x_defined_color(f, name, color_def, alloc) \
121 ns_defined_color (f, name, color_def, alloc, 0)
122 #define FRAME_X_SCREEN(f) 0
123 #define DefaultDepthOfScreen(screen) x_display_list->n_planes
127 /* The symbol `postscript' identifying images of this type. */
129 static Lisp_Object Qpostscript
;
131 static void x_disable_image (struct frame
*, struct image
*);
132 static void x_edge_detection (struct frame
*, struct image
*, Lisp_Object
,
135 static void init_color_table (void);
136 static unsigned long lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
);
137 #ifdef COLOR_TABLE_SUPPORT
138 static void free_color_table (void);
139 static unsigned long *colors_in_color_table (int *n
);
142 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
143 id, which is just an int that this section returns. Bitmaps are
144 reference counted so they can be shared among frames.
146 Bitmap indices are guaranteed to be > 0, so a negative number can
147 be used to indicate no bitmap.
149 If you use x_create_bitmap_from_data, then you must keep track of
150 the bitmaps yourself. That is, creating a bitmap from the same
151 data more than once will not be caught. */
155 XGetImage (Display
*display
, Pixmap pixmap
, int x
, int y
,
156 unsigned int width
, unsigned int height
,
157 unsigned long plane_mask
, int format
)
159 /* TODO: not sure what this function is supposed to do.. */
160 ns_retain_object (pixmap
);
164 /* use with imgs created by ns_image_for_XPM */
166 XGetPixel (XImagePtr ximage
, int x
, int y
)
168 return ns_get_pixel (ximage
, x
, y
);
171 /* use with imgs created by ns_image_for_XPM; alpha set to 1;
172 pixel is assumed to be in form RGB */
174 XPutPixel (XImagePtr ximage
, int x
, int y
, unsigned long pixel
)
176 ns_put_pixel (ximage
, x
, y
, pixel
);
181 /* Functions to access the contents of a bitmap, given an id. */
184 x_bitmap_height (FRAME_PTR f
, ptrdiff_t id
)
186 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
190 x_bitmap_width (FRAME_PTR f
, ptrdiff_t id
)
192 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
195 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
197 x_bitmap_pixmap (FRAME_PTR f
, ptrdiff_t id
)
199 /* HAVE_NTGUI needs the explicit cast here. */
200 return (int) FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
204 #ifdef HAVE_X_WINDOWS
206 x_bitmap_mask (FRAME_PTR f
, ptrdiff_t id
)
208 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].mask
;
212 /* Allocate a new bitmap record. Returns index of new record. */
215 x_allocate_bitmap_record (FRAME_PTR f
)
217 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
220 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
221 return ++dpyinfo
->bitmaps_last
;
223 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
224 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
228 xpalloc (dpyinfo
->bitmaps
, &dpyinfo
->bitmaps_size
,
229 10, -1, sizeof *dpyinfo
->bitmaps
);
230 return ++dpyinfo
->bitmaps_last
;
233 /* Add one reference to the reference count of the bitmap with id ID. */
236 x_reference_bitmap (FRAME_PTR f
, ptrdiff_t id
)
238 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
241 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
244 x_create_bitmap_from_data (struct frame
*f
, char *bits
, unsigned int width
, unsigned int height
)
246 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
249 #ifdef HAVE_X_WINDOWS
251 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
252 bits
, width
, height
);
255 #endif /* HAVE_X_WINDOWS */
259 bitmap
= CreateBitmap (width
, height
,
260 FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_planes
,
261 FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_cbits
,
265 #endif /* HAVE_NTGUI */
268 void *bitmap
= ns_image_from_XBM (bits
, width
, height
);
273 id
= x_allocate_bitmap_record (f
);
276 dpyinfo
->bitmaps
[id
- 1].img
= bitmap
;
277 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
280 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
281 dpyinfo
->bitmaps
[id
- 1].height
= height
;
282 dpyinfo
->bitmaps
[id
- 1].width
= width
;
283 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
285 #ifdef HAVE_X_WINDOWS
286 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
287 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
288 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
289 #endif /* HAVE_X_WINDOWS */
292 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
293 dpyinfo
->bitmaps
[id
- 1].hinst
= NULL
;
294 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
295 #endif /* HAVE_NTGUI */
300 /* Create bitmap from file FILE for frame F. */
303 x_create_bitmap_from_file (struct frame
*f
, Lisp_Object file
)
305 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
308 return -1; /* W32_TODO : bitmap support */
309 #endif /* HAVE_NTGUI */
313 void *bitmap
= ns_image_from_file (file
);
319 id
= x_allocate_bitmap_record (f
);
320 dpyinfo
->bitmaps
[id
- 1].img
= bitmap
;
321 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
322 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (SBYTES (file
) + 1);
323 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
324 dpyinfo
->bitmaps
[id
- 1].height
= ns_image_width (bitmap
);
325 dpyinfo
->bitmaps
[id
- 1].width
= ns_image_height (bitmap
);
326 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SDATA (file
));
330 #ifdef HAVE_X_WINDOWS
331 unsigned int width
, height
;
333 int xhot
, yhot
, result
;
339 /* Look for an existing bitmap with the same name. */
340 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
342 if (dpyinfo
->bitmaps
[id
].refcount
343 && dpyinfo
->bitmaps
[id
].file
344 && !strcmp (dpyinfo
->bitmaps
[id
].file
, SSDATA (file
)))
346 ++dpyinfo
->bitmaps
[id
].refcount
;
351 /* Search bitmap-file-path for the file, if appropriate. */
352 fd
= openp (Vx_bitmap_file_path
, file
, Qnil
, &found
, Qnil
);
357 filename
= SSDATA (found
);
359 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
360 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
361 if (result
!= BitmapSuccess
)
364 id
= x_allocate_bitmap_record (f
);
365 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
366 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
367 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
368 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (SBYTES (file
) + 1);
369 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
370 dpyinfo
->bitmaps
[id
- 1].height
= height
;
371 dpyinfo
->bitmaps
[id
- 1].width
= width
;
372 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SSDATA (file
));
375 #endif /* HAVE_X_WINDOWS */
381 free_bitmap_record (Display_Info
*dpyinfo
, Bitmap_Record
*bm
)
383 #ifdef HAVE_X_WINDOWS
384 XFreePixmap (dpyinfo
->display
, bm
->pixmap
);
386 XFreePixmap (dpyinfo
->display
, bm
->mask
);
387 #endif /* HAVE_X_WINDOWS */
390 DeleteObject (bm
->pixmap
);
391 #endif /* HAVE_NTGUI */
394 ns_release_object (bm
->img
);
404 /* Remove reference to bitmap with id number ID. */
407 x_destroy_bitmap (FRAME_PTR f
, ptrdiff_t id
)
409 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
413 Bitmap_Record
*bm
= &dpyinfo
->bitmaps
[id
- 1];
415 if (--bm
->refcount
== 0)
418 free_bitmap_record (dpyinfo
, bm
);
424 /* Free all the bitmaps for the display specified by DPYINFO. */
427 x_destroy_all_bitmaps (Display_Info
*dpyinfo
)
430 Bitmap_Record
*bm
= dpyinfo
->bitmaps
;
432 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++, bm
++)
433 if (bm
->refcount
> 0)
434 free_bitmap_record (dpyinfo
, bm
);
436 dpyinfo
->bitmaps_last
= 0;
440 #ifdef HAVE_X_WINDOWS
442 /* Useful functions defined in the section
443 `Image type independent image structures' below. */
445 static unsigned long four_corners_best (XImagePtr ximg
,
448 unsigned long height
);
450 static int x_create_x_image_and_pixmap (struct frame
*f
, int width
, int height
,
451 int depth
, XImagePtr
*ximg
,
454 static void x_destroy_x_image (XImagePtr ximg
);
457 /* Create a mask of a bitmap. Note is this not a perfect mask.
458 It's nicer with some borders in this context */
461 x_create_bitmap_mask (struct frame
*f
, ptrdiff_t id
)
464 XImagePtr ximg
, mask_img
;
465 unsigned long width
, height
;
468 unsigned long x
, y
, xp
, xm
, yp
, ym
;
471 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
476 pixmap
= x_bitmap_pixmap (f
, id
);
477 width
= x_bitmap_width (f
, id
);
478 height
= x_bitmap_height (f
, id
);
481 ximg
= XGetImage (FRAME_X_DISPLAY (f
), pixmap
, 0, 0, width
, height
,
490 result
= x_create_x_image_and_pixmap (f
, width
, height
, 1, &mask_img
, &mask
);
495 XDestroyImage (ximg
);
499 bg
= four_corners_best (ximg
, NULL
, width
, height
);
501 for (y
= 0; y
< ximg
->height
; ++y
)
503 for (x
= 0; x
< ximg
->width
; ++x
)
505 xp
= x
!= ximg
->width
- 1 ? x
+ 1 : 0;
506 xm
= x
!= 0 ? x
- 1 : ximg
->width
- 1;
507 yp
= y
!= ximg
->height
- 1 ? y
+ 1 : 0;
508 ym
= y
!= 0 ? y
- 1 : ximg
->height
- 1;
509 if (XGetPixel (ximg
, x
, y
) == bg
510 && XGetPixel (ximg
, x
, yp
) == bg
511 && XGetPixel (ximg
, x
, ym
) == bg
512 && XGetPixel (ximg
, xp
, y
) == bg
513 && XGetPixel (ximg
, xp
, yp
) == bg
514 && XGetPixel (ximg
, xp
, ym
) == bg
515 && XGetPixel (ximg
, xm
, y
) == bg
516 && XGetPixel (ximg
, xm
, yp
) == bg
517 && XGetPixel (ximg
, xm
, ym
) == bg
)
518 XPutPixel (mask_img
, x
, y
, 0);
520 XPutPixel (mask_img
, x
, y
, 1);
524 eassert (interrupt_input_blocked
);
525 gc
= XCreateGC (FRAME_X_DISPLAY (f
), mask
, 0, NULL
);
526 XPutImage (FRAME_X_DISPLAY (f
), mask
, gc
, mask_img
, 0, 0, 0, 0,
528 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
530 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
531 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
533 XDestroyImage (ximg
);
534 x_destroy_x_image (mask_img
);
539 #endif /* HAVE_X_WINDOWS */
542 /***********************************************************************
544 ***********************************************************************/
546 /* List of supported image types. Use define_image_type to add new
547 types. Use lookup_image_type to find a type for a given symbol. */
549 static struct image_type
*image_types
;
551 /* The symbol `xbm' which is used as the type symbol for XBM images. */
553 static Lisp_Object Qxbm
;
557 Lisp_Object QCascent
, QCmargin
, QCrelief
;
558 Lisp_Object QCconversion
;
559 static Lisp_Object QCheuristic_mask
;
560 static Lisp_Object QCcolor_symbols
;
561 static Lisp_Object QCindex
, QCmatrix
, QCcolor_adjustment
, QCmask
, QCgeometry
;
562 static Lisp_Object QCcrop
, QCrotation
;
566 static Lisp_Object Qcount
, Qextension_data
, Qdelay
;
567 static Lisp_Object Qlaplace
, Qemboss
, Qedge_detection
, Qheuristic
;
569 /* Function prototypes. */
571 static Lisp_Object
define_image_type (struct image_type
*type
, int loaded
);
572 static struct image_type
*lookup_image_type (Lisp_Object symbol
);
573 static void image_error (const char *format
, Lisp_Object
, Lisp_Object
);
574 static void x_laplace (struct frame
*, struct image
*);
575 static void x_emboss (struct frame
*, struct image
*);
576 static int x_build_heuristic_mask (struct frame
*, struct image
*,
579 #define CACHE_IMAGE_TYPE(type, status) \
580 do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
582 #define CACHE_IMAGE_TYPE(type, status)
585 #define ADD_IMAGE_TYPE(type) \
586 do { Vimage_types = Fcons (type, Vimage_types); } while (0)
588 /* Define a new image type from TYPE. This adds a copy of TYPE to
589 image_types and caches the loading status of TYPE. */
592 define_image_type (struct image_type
*type
, int loaded
)
600 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
601 The initialized data segment is read-only. */
602 struct image_type
*p
= (struct image_type
*) xmalloc (sizeof *p
);
603 memcpy (p
, type
, sizeof *p
);
604 p
->next
= image_types
;
609 CACHE_IMAGE_TYPE (*type
->type
, success
);
614 /* Look up image type SYMBOL, and return a pointer to its image_type
615 structure. Value is null if SYMBOL is not a known image type. */
617 static inline struct image_type
*
618 lookup_image_type (Lisp_Object symbol
)
620 struct image_type
*type
;
622 /* We must initialize the image-type if it hasn't been already. */
623 if (NILP (Finit_image_library (symbol
, Vdynamic_library_alist
)))
624 return 0; /* unimplemented */
626 for (type
= image_types
; type
; type
= type
->next
)
627 if (EQ (symbol
, *type
->type
))
634 /* Value is non-zero if OBJECT is a valid Lisp image specification. A
635 valid image specification is a list whose car is the symbol
636 `image', and whose rest is a property list. The property list must
637 contain a value for key `:type'. That value must be the name of a
638 supported image type. The rest of the property list depends on the
642 valid_image_p (Lisp_Object object
)
650 for (tem
= XCDR (object
); CONSP (tem
); tem
= XCDR (tem
))
651 if (EQ (XCAR (tem
), QCtype
))
654 if (CONSP (tem
) && SYMBOLP (XCAR (tem
)))
656 struct image_type
*type
;
657 type
= lookup_image_type (XCAR (tem
));
659 valid_p
= type
->valid_p (object
);
670 /* Log error message with format string FORMAT and argument ARG.
671 Signaling an error, e.g. when an image cannot be loaded, is not a
672 good idea because this would interrupt redisplay, and the error
673 message display would lead to another redisplay. This function
674 therefore simply displays a message. */
677 image_error (const char *format
, Lisp_Object arg1
, Lisp_Object arg2
)
679 add_to_log (format
, arg1
, arg2
);
684 /***********************************************************************
686 ***********************************************************************/
688 enum image_value_type
690 IMAGE_DONT_CHECK_VALUE_TYPE
,
692 IMAGE_STRING_OR_NIL_VALUE
,
694 IMAGE_POSITIVE_INTEGER_VALUE
,
695 IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
,
696 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
699 IMAGE_FUNCTION_VALUE
,
704 /* Structure used when parsing image specifications. */
708 /* Name of keyword. */
711 /* The type of value allowed. */
712 enum image_value_type type
;
714 /* Non-zero means key must be present. */
717 /* Used to recognize duplicate keywords in a property list. */
720 /* The value that was found. */
725 static int parse_image_spec (Lisp_Object
, struct image_keyword
*,
727 static Lisp_Object
image_spec_value (Lisp_Object
, Lisp_Object
, int *);
730 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
731 has the format (image KEYWORD VALUE ...). One of the keyword/
732 value pairs must be `:type TYPE'. KEYWORDS is a vector of
733 image_keywords structures of size NKEYWORDS describing other
734 allowed keyword/value pairs. Value is non-zero if SPEC is valid. */
737 parse_image_spec (Lisp_Object spec
, struct image_keyword
*keywords
,
738 int nkeywords
, Lisp_Object type
)
747 while (CONSP (plist
))
749 Lisp_Object key
, value
;
751 /* First element of a pair must be a symbol. */
753 plist
= XCDR (plist
);
757 /* There must follow a value. */
760 value
= XCAR (plist
);
761 plist
= XCDR (plist
);
763 /* Find key in KEYWORDS. Error if not found. */
764 for (i
= 0; i
< nkeywords
; ++i
)
765 if (strcmp (keywords
[i
].name
, SSDATA (SYMBOL_NAME (key
))) == 0)
771 /* Record that we recognized the keyword. If a keywords
772 was found more than once, it's an error. */
773 keywords
[i
].value
= value
;
774 if (keywords
[i
].count
> 1)
778 /* Check type of value against allowed type. */
779 switch (keywords
[i
].type
)
781 case IMAGE_STRING_VALUE
:
782 if (!STRINGP (value
))
786 case IMAGE_STRING_OR_NIL_VALUE
:
787 if (!STRINGP (value
) && !NILP (value
))
791 case IMAGE_SYMBOL_VALUE
:
792 if (!SYMBOLP (value
))
796 case IMAGE_POSITIVE_INTEGER_VALUE
:
797 if (! RANGED_INTEGERP (1, value
, INT_MAX
))
801 case IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
:
802 if (RANGED_INTEGERP (0, value
, INT_MAX
))
805 && RANGED_INTEGERP (0, XCAR (value
), INT_MAX
)
806 && RANGED_INTEGERP (0, XCDR (value
), INT_MAX
))
810 case IMAGE_ASCENT_VALUE
:
811 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
813 else if (RANGED_INTEGERP (0, value
, 100))
817 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
818 /* Unlike the other integer-related cases, this one does not
819 verify that VALUE fits in 'int'. This is because callers
821 if (!INTEGERP (value
) || XINT (value
) < 0)
825 case IMAGE_DONT_CHECK_VALUE_TYPE
:
828 case IMAGE_FUNCTION_VALUE
:
829 value
= indirect_function (value
);
830 if (!NILP (Ffunctionp (value
)))
834 case IMAGE_NUMBER_VALUE
:
835 if (!INTEGERP (value
) && !FLOATP (value
))
839 case IMAGE_INTEGER_VALUE
:
840 if (! TYPE_RANGED_INTEGERP (int, value
))
844 case IMAGE_BOOL_VALUE
:
845 if (!NILP (value
) && !EQ (value
, Qt
))
854 if (EQ (key
, QCtype
) && !EQ (type
, value
))
858 /* Check that all mandatory fields are present. */
859 for (i
= 0; i
< nkeywords
; ++i
)
860 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
867 /* Return the value of KEY in image specification SPEC. Value is nil
868 if KEY is not present in SPEC. if FOUND is not null, set *FOUND
869 to 1 if KEY was found in SPEC, set it to 0 otherwise. */
872 image_spec_value (Lisp_Object spec
, Lisp_Object key
, int *found
)
876 eassert (valid_image_p (spec
));
878 for (tail
= XCDR (spec
);
879 CONSP (tail
) && CONSP (XCDR (tail
));
880 tail
= XCDR (XCDR (tail
)))
882 if (EQ (XCAR (tail
), key
))
886 return XCAR (XCDR (tail
));
896 DEFUN ("image-size", Fimage_size
, Simage_size
, 1, 3, 0,
897 doc
: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
898 PIXELS non-nil means return the size in pixels, otherwise return the
899 size in canonical character units.
900 FRAME is the frame on which the image will be displayed. FRAME nil
901 or omitted means use the selected frame. */)
902 (Lisp_Object spec
, Lisp_Object pixels
, Lisp_Object frame
)
907 if (valid_image_p (spec
))
909 struct frame
*f
= check_x_frame (frame
);
910 ptrdiff_t id
= lookup_image (f
, spec
);
911 struct image
*img
= IMAGE_FROM_ID (f
, id
);
912 int width
= img
->width
+ 2 * img
->hmargin
;
913 int height
= img
->height
+ 2 * img
->vmargin
;
916 size
= Fcons (make_float ((double) width
/ FRAME_COLUMN_WIDTH (f
)),
917 make_float ((double) height
/ FRAME_LINE_HEIGHT (f
)));
919 size
= Fcons (make_number (width
), make_number (height
));
922 error ("Invalid image specification");
928 DEFUN ("image-mask-p", Fimage_mask_p
, Simage_mask_p
, 1, 2, 0,
929 doc
: /* Return t if image SPEC has a mask bitmap.
930 FRAME is the frame on which the image will be displayed. FRAME nil
931 or omitted means use the selected frame. */)
932 (Lisp_Object spec
, Lisp_Object frame
)
937 if (valid_image_p (spec
))
939 struct frame
*f
= check_x_frame (frame
);
940 ptrdiff_t id
= lookup_image (f
, spec
);
941 struct image
*img
= IMAGE_FROM_ID (f
, id
);
946 error ("Invalid image specification");
951 DEFUN ("image-metadata", Fimage_metadata
, Simage_metadata
, 1, 2, 0,
952 doc
: /* Return metadata for image SPEC.
953 FRAME is the frame on which the image will be displayed. FRAME nil
954 or omitted means use the selected frame. */)
955 (Lisp_Object spec
, Lisp_Object frame
)
960 if (valid_image_p (spec
))
962 struct frame
*f
= check_x_frame (frame
);
963 ptrdiff_t id
= lookup_image (f
, spec
);
964 struct image
*img
= IMAGE_FROM_ID (f
, id
);
965 ext
= img
->lisp_data
;
972 /***********************************************************************
973 Image type independent image structures
974 ***********************************************************************/
976 static void free_image (struct frame
*f
, struct image
*img
);
978 #define MAX_IMAGE_SIZE 10.0
979 /* Allocate and return a new image structure for image specification
980 SPEC. SPEC has a hash value of HASH. */
982 static struct image
*
983 make_image (Lisp_Object spec
, EMACS_UINT hash
)
985 struct image
*img
= (struct image
*) xmalloc (sizeof *img
);
986 Lisp_Object file
= image_spec_value (spec
, QCfile
, NULL
);
988 eassert (valid_image_p (spec
));
989 memset (img
, 0, sizeof *img
);
990 img
->dependencies
= NILP (file
) ? Qnil
: list1 (file
);
991 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
992 eassert (img
->type
!= NULL
);
994 img
->lisp_data
= Qnil
;
995 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
997 img
->corners
[BOT_CORNER
] = -1; /* Full image */
1002 /* Free image IMG which was used on frame F, including its resources. */
1005 free_image (struct frame
*f
, struct image
*img
)
1009 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1011 /* Remove IMG from the hash table of its cache. */
1013 img
->prev
->next
= img
->next
;
1015 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
1018 img
->next
->prev
= img
->prev
;
1020 c
->images
[img
->id
] = NULL
;
1022 /* Free resources, then free IMG. */
1023 img
->type
->free (f
, img
);
1028 /* Return 1 if the given widths and heights are valid for display;
1029 otherwise, return 0. */
1032 check_image_size (struct frame
*f
, int width
, int height
)
1036 if (width
<= 0 || height
<= 0)
1039 if (INTEGERP (Vmax_image_size
))
1040 return (width
<= XINT (Vmax_image_size
)
1041 && height
<= XINT (Vmax_image_size
));
1042 else if (FLOATP (Vmax_image_size
))
1046 w
= FRAME_PIXEL_WIDTH (f
);
1047 h
= FRAME_PIXEL_HEIGHT (f
);
1050 w
= h
= 1024; /* Arbitrary size for unknown frame. */
1051 return (width
<= XFLOAT_DATA (Vmax_image_size
) * w
1052 && height
<= XFLOAT_DATA (Vmax_image_size
) * h
);
1058 /* Prepare image IMG for display on frame F. Must be called before
1059 drawing an image. */
1062 prepare_image_for_display (struct frame
*f
, struct image
*img
)
1064 /* We're about to display IMG, so set its timestamp to `now'. */
1065 EMACS_GET_TIME (img
->timestamp
);
1067 /* If IMG doesn't have a pixmap yet, load it now, using the image
1068 type dependent loader function. */
1069 if (img
->pixmap
== NO_PIXMAP
&& !img
->load_failed_p
)
1070 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
1075 /* Value is the number of pixels for the ascent of image IMG when
1076 drawn in face FACE. */
1079 image_ascent (struct image
*img
, struct face
*face
, struct glyph_slice
*slice
)
1084 if (slice
->height
== img
->height
)
1085 height
= img
->height
+ img
->vmargin
;
1086 else if (slice
->y
== 0)
1087 height
= slice
->height
+ img
->vmargin
;
1089 height
= slice
->height
;
1091 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
1096 /* W32 specific version. Why?. ++kfs */
1097 ascent
= height
/ 2 - (FONT_DESCENT (face
->font
)
1098 - FONT_BASE (face
->font
)) / 2;
1100 /* This expression is arranged so that if the image can't be
1101 exactly centered, it will be moved slightly up. This is
1102 because a typical font is `top-heavy' (due to the presence
1103 uppercase letters), so the image placement should err towards
1104 being top-heavy too. It also just generally looks better. */
1105 ascent
= (height
+ FONT_BASE (face
->font
)
1106 - FONT_DESCENT (face
->font
) + 1) / 2;
1107 #endif /* HAVE_NTGUI */
1110 ascent
= height
/ 2;
1113 ascent
= height
* (img
->ascent
/ 100.0);
1119 /* Image background colors. */
1121 /* Find the "best" corner color of a bitmap.
1122 On W32, XIMG is assumed to a device context with the bitmap selected. */
1124 static RGB_PIXEL_COLOR
1125 four_corners_best (XImagePtr_or_DC ximg
, int *corners
,
1126 unsigned long width
, unsigned long height
)
1128 RGB_PIXEL_COLOR corner_pixels
[4], best
IF_LINT (= 0);
1131 if (corners
&& corners
[BOT_CORNER
] >= 0)
1133 /* Get the colors at the corner_pixels of ximg. */
1134 corner_pixels
[0] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[TOP_CORNER
]);
1135 corner_pixels
[1] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[TOP_CORNER
]);
1136 corner_pixels
[2] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[BOT_CORNER
] - 1);
1137 corner_pixels
[3] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[BOT_CORNER
] - 1);
1141 /* Get the colors at the corner_pixels of ximg. */
1142 corner_pixels
[0] = GET_PIXEL (ximg
, 0, 0);
1143 corner_pixels
[1] = GET_PIXEL (ximg
, width
- 1, 0);
1144 corner_pixels
[2] = GET_PIXEL (ximg
, width
- 1, height
- 1);
1145 corner_pixels
[3] = GET_PIXEL (ximg
, 0, height
- 1);
1147 /* Choose the most frequently found color as background. */
1148 for (i
= best_count
= 0; i
< 4; ++i
)
1152 for (j
= n
= 0; j
< 4; ++j
)
1153 if (corner_pixels
[i
] == corner_pixels
[j
])
1157 best
= corner_pixels
[i
], best_count
= n
;
1163 /* Portability macros */
1167 #define Destroy_Image(img_dc, prev) \
1168 do { SelectObject (img_dc, prev); DeleteDC (img_dc); } while (0)
1170 #define Free_Pixmap(display, pixmap) \
1171 DeleteObject (pixmap)
1173 #elif defined (HAVE_NS)
1175 #define Destroy_Image(ximg, dummy) \
1176 ns_release_object (ximg)
1178 #define Free_Pixmap(display, pixmap) \
1179 ns_release_object (pixmap)
1183 #define Destroy_Image(ximg, dummy) \
1184 XDestroyImage (ximg)
1186 #define Free_Pixmap(display, pixmap) \
1187 XFreePixmap (display, pixmap)
1189 #endif /* !HAVE_NTGUI && !HAVE_NS */
1192 /* Return the `background' field of IMG. If IMG doesn't have one yet,
1193 it is guessed heuristically. If non-zero, XIMG is an existing
1194 XImage object (or device context with the image selected on W32) to
1195 use for the heuristic. */
1198 image_background (struct image
*img
, struct frame
*f
, XImagePtr_or_DC ximg
)
1200 if (! img
->background_valid
)
1201 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1203 int free_ximg
= !ximg
;
1206 #endif /* HAVE_NTGUI */
1211 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
1212 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
1214 HDC frame_dc
= get_frame_dc (f
);
1215 ximg
= CreateCompatibleDC (frame_dc
);
1216 release_frame_dc (f
, frame_dc
);
1217 prev
= SelectObject (ximg
, img
->pixmap
);
1218 #endif /* !HAVE_NTGUI */
1221 img
->background
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
1224 Destroy_Image (ximg
, prev
);
1226 img
->background_valid
= 1;
1229 return img
->background
;
1232 /* Return the `background_transparent' field of IMG. If IMG doesn't
1233 have one yet, it is guessed heuristically. If non-zero, MASK is an
1234 existing XImage object to use for the heuristic. */
1237 image_background_transparent (struct image
*img
, struct frame
*f
, XImagePtr_or_DC mask
)
1239 if (! img
->background_transparent_valid
)
1240 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1244 int free_mask
= !mask
;
1247 #endif /* HAVE_NTGUI */
1252 mask
= XGetImage (FRAME_X_DISPLAY (f
), img
->mask
,
1253 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
1255 HDC frame_dc
= get_frame_dc (f
);
1256 mask
= CreateCompatibleDC (frame_dc
);
1257 release_frame_dc (f
, frame_dc
);
1258 prev
= SelectObject (mask
, img
->mask
);
1259 #endif /* HAVE_NTGUI */
1262 img
->background_transparent
1263 = (four_corners_best (mask
, img
->corners
, img
->width
, img
->height
) == PIX_MASK_RETAIN
);
1266 Destroy_Image (mask
, prev
);
1269 img
->background_transparent
= 0;
1271 img
->background_transparent_valid
= 1;
1274 return img
->background_transparent
;
1278 /***********************************************************************
1279 Helper functions for X image types
1280 ***********************************************************************/
1282 static void x_clear_image_1 (struct frame
*, struct image
*, int,
1284 static void x_clear_image (struct frame
*f
, struct image
*img
);
1285 static unsigned long x_alloc_image_color (struct frame
*f
,
1287 Lisp_Object color_name
,
1288 unsigned long dflt
);
1291 /* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
1292 free the pixmap if any. MASK_P non-zero means clear the mask
1293 pixmap if any. COLORS_P non-zero means free colors allocated for
1294 the image, if any. */
1297 x_clear_image_1 (struct frame
*f
, struct image
*img
, int pixmap_p
, int mask_p
,
1300 if (pixmap_p
&& img
->pixmap
)
1302 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
1303 img
->pixmap
= NO_PIXMAP
;
1304 /* NOTE (HAVE_NS): background color is NOT an indexed color! */
1305 img
->background_valid
= 0;
1308 if (mask_p
&& img
->mask
)
1310 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
1311 img
->mask
= NO_PIXMAP
;
1312 img
->background_transparent_valid
= 0;
1315 if (colors_p
&& img
->ncolors
)
1317 /* W32_TODO: color table support. */
1318 #ifdef HAVE_X_WINDOWS
1319 x_free_colors (f
, img
->colors
, img
->ncolors
);
1320 #endif /* HAVE_X_WINDOWS */
1321 xfree (img
->colors
);
1328 /* Free X resources of image IMG which is used on frame F. */
1331 x_clear_image (struct frame
*f
, struct image
*img
)
1334 x_clear_image_1 (f
, img
, 1, 1, 1);
1339 /* Allocate color COLOR_NAME for image IMG on frame F. If color
1340 cannot be allocated, use DFLT. Add a newly allocated color to
1341 IMG->colors, so that it can be freed again. Value is the pixel
1344 static unsigned long
1345 x_alloc_image_color (struct frame
*f
, struct image
*img
, Lisp_Object color_name
,
1349 unsigned long result
;
1351 eassert (STRINGP (color_name
));
1353 if (x_defined_color (f
, SSDATA (color_name
), &color
, 1)
1354 && img
->ncolors
< min (min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *img
->colors
,
1357 /* This isn't called frequently so we get away with simply
1358 reallocating the color vector to the needed size, here. */
1359 ptrdiff_t ncolors
= img
->ncolors
+ 1;
1361 (unsigned long *) xrealloc (img
->colors
,
1362 ncolors
* sizeof *img
->colors
);
1363 img
->colors
[ncolors
- 1] = color
.pixel
;
1364 img
->ncolors
= ncolors
;
1365 result
= color
.pixel
;
1375 /***********************************************************************
1377 ***********************************************************************/
1379 static void cache_image (struct frame
*f
, struct image
*img
);
1380 static void postprocess_image (struct frame
*, struct image
*);
1382 /* Return a new, initialized image cache that is allocated from the
1383 heap. Call free_image_cache to free an image cache. */
1385 struct image_cache
*
1386 make_image_cache (void)
1388 struct image_cache
*c
= (struct image_cache
*) xmalloc (sizeof *c
);
1391 memset (c
, 0, sizeof *c
);
1393 c
->images
= (struct image
**) xmalloc (size
* sizeof *c
->images
);
1395 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
1396 c
->buckets
= (struct image
**) xmalloc (size
);
1397 memset (c
->buckets
, 0, size
);
1402 /* Find an image matching SPEC in the cache, and return it. If no
1403 image is found, return NULL. */
1404 static struct image
*
1405 search_image_cache (struct frame
*f
, Lisp_Object spec
, EMACS_UINT hash
)
1408 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1409 int i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1411 if (!c
) return NULL
;
1413 /* If the image spec does not specify a background color, the cached
1414 image must have the same background color as the current frame.
1415 The foreground color must also match, for the sake of monochrome
1418 In fact, we could ignore the foreground color matching condition
1419 for color images, or if the image spec specifies :foreground;
1420 similarly we could ignore the background color matching condition
1421 for formats that don't use transparency (such as jpeg), or if the
1422 image spec specifies :background. However, the extra memory
1423 usage is probably negligible in practice, so we don't bother. */
1425 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
1426 if (img
->hash
== hash
1427 && !NILP (Fequal (img
->spec
, spec
))
1428 && img
->frame_foreground
== FRAME_FOREGROUND_PIXEL (f
)
1429 && img
->frame_background
== FRAME_BACKGROUND_PIXEL (f
))
1435 /* Search frame F for an image with spec SPEC, and free it. */
1438 uncache_image (struct frame
*f
, Lisp_Object spec
)
1440 struct image
*img
= search_image_cache (f
, spec
, sxhash (spec
, 0));
1443 free_image (f
, img
);
1444 /* As display glyphs may still be referring to the image ID, we
1445 must garbage the frame (Bug#6426). */
1446 SET_FRAME_GARBAGED (f
);
1451 /* Free image cache of frame F. Be aware that X frames share images
1455 free_image_cache (struct frame
*f
)
1457 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1462 /* Cache should not be referenced by any frame when freed. */
1463 eassert (c
->refcount
== 0);
1465 for (i
= 0; i
< c
->used
; ++i
)
1466 free_image (f
, c
->images
[i
]);
1470 FRAME_IMAGE_CACHE (f
) = NULL
;
1475 /* Clear image cache of frame F. FILTER=t means free all images.
1476 FILTER=nil means clear only images that haven't been
1477 displayed for some time.
1478 Else, only free the images which have FILTER in their `dependencies'.
1479 Should be called from time to time to reduce the number of loaded images.
1480 If image-cache-eviction-delay is non-nil, this frees images in the cache
1481 which weren't displayed for at least that many seconds. */
1484 clear_image_cache (struct frame
*f
, Lisp_Object filter
)
1486 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1490 ptrdiff_t i
, nfreed
= 0;
1492 /* Block input so that we won't be interrupted by a SIGIO
1493 while being in an inconsistent state. */
1498 /* Filter image cache. */
1499 for (i
= 0; i
< c
->used
; ++i
)
1501 struct image
*img
= c
->images
[i
];
1502 if (img
&& (EQ (Qt
, filter
)
1503 || !NILP (Fmember (filter
, img
->dependencies
))))
1505 free_image (f
, img
);
1510 else if (INTEGERP (Vimage_cache_eviction_delay
))
1512 /* Free cache based on timestamp. */
1515 ptrdiff_t nimages
= 0;
1517 for (i
= 0; i
< c
->used
; ++i
)
1521 /* If the number of cached images has grown unusually large,
1522 decrease the cache eviction delay (Bug#6230). */
1523 delay
= XINT (Vimage_cache_eviction_delay
);
1525 delay
= 1600 * delay
/ nimages
/ nimages
;
1526 delay
= max (delay
, 1);
1529 EMACS_SUB_TIME (old
, t
, EMACS_TIME_FROM_DOUBLE (delay
));
1531 for (i
= 0; i
< c
->used
; ++i
)
1533 struct image
*img
= c
->images
[i
];
1534 if (img
&& EMACS_TIME_LT (img
->timestamp
, old
))
1536 free_image (f
, img
);
1542 /* We may be clearing the image cache because, for example,
1543 Emacs was iconified for a longer period of time. In that
1544 case, current matrices may still contain references to
1545 images freed above. So, clear these matrices. */
1548 Lisp_Object tail
, frame
;
1550 FOR_EACH_FRAME (tail
, frame
)
1552 struct frame
*fr
= XFRAME (frame
);
1553 if (FRAME_IMAGE_CACHE (fr
) == c
)
1554 clear_current_matrices (fr
);
1557 ++windows_or_buffers_changed
;
1565 clear_image_caches (Lisp_Object filter
)
1567 /* FIXME: We want to do
1568 * struct terminal *t;
1569 * for (t = terminal_list; t; t = t->next_terminal)
1570 * clear_image_cache (t, filter); */
1571 Lisp_Object tail
, frame
;
1572 FOR_EACH_FRAME (tail
, frame
)
1573 if (FRAME_WINDOW_P (XFRAME (frame
)))
1574 clear_image_cache (XFRAME (frame
), filter
);
1577 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
1579 doc
: /* Clear the image cache.
1580 FILTER nil or a frame means clear all images in the selected frame.
1581 FILTER t means clear the image caches of all frames.
1582 Anything else, means only clear those images which refer to FILTER,
1583 which is then usually a filename. */)
1584 (Lisp_Object filter
)
1586 if (!(EQ (filter
, Qnil
) || FRAMEP (filter
)))
1587 clear_image_caches (filter
);
1589 clear_image_cache (check_x_frame (filter
), Qt
);
1595 DEFUN ("image-flush", Fimage_flush
, Simage_flush
,
1597 doc
: /* Fush the image with specification SPEC on frame FRAME.
1598 This removes the image from the Emacs image cache. If SPEC specifies
1599 an image file, the next redisplay of this image will read from the
1600 current contents of that file.
1602 FRAME nil or omitted means use the selected frame.
1603 FRAME t means refresh the image on all frames. */)
1604 (Lisp_Object spec
, Lisp_Object frame
)
1606 if (!valid_image_p (spec
))
1607 error ("Invalid image specification");
1612 FOR_EACH_FRAME (tail
, frame
)
1614 struct frame
*f
= XFRAME (frame
);
1615 if (FRAME_WINDOW_P (f
))
1616 uncache_image (f
, spec
);
1620 uncache_image (check_x_frame (frame
), spec
);
1626 /* Compute masks and transform image IMG on frame F, as specified
1627 by the image's specification, */
1630 postprocess_image (struct frame
*f
, struct image
*img
)
1632 /* Manipulation of the image's mask. */
1635 Lisp_Object conversion
, spec
;
1640 /* `:heuristic-mask t'
1642 means build a mask heuristically.
1643 `:heuristic-mask (R G B)'
1644 `:mask (heuristic (R G B))'
1645 means build a mask from color (R G B) in the
1648 means remove a mask, if any. */
1650 mask
= image_spec_value (spec
, QCheuristic_mask
, NULL
);
1652 x_build_heuristic_mask (f
, img
, mask
);
1657 mask
= image_spec_value (spec
, QCmask
, &found_p
);
1659 if (EQ (mask
, Qheuristic
))
1660 x_build_heuristic_mask (f
, img
, Qt
);
1661 else if (CONSP (mask
)
1662 && EQ (XCAR (mask
), Qheuristic
))
1664 if (CONSP (XCDR (mask
)))
1665 x_build_heuristic_mask (f
, img
, XCAR (XCDR (mask
)));
1667 x_build_heuristic_mask (f
, img
, XCDR (mask
));
1669 else if (NILP (mask
) && found_p
&& img
->mask
)
1671 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
1672 img
->mask
= NO_PIXMAP
;
1677 /* Should we apply an image transformation algorithm? */
1678 conversion
= image_spec_value (spec
, QCconversion
, NULL
);
1679 if (EQ (conversion
, Qdisabled
))
1680 x_disable_image (f
, img
);
1681 else if (EQ (conversion
, Qlaplace
))
1683 else if (EQ (conversion
, Qemboss
))
1685 else if (CONSP (conversion
)
1686 && EQ (XCAR (conversion
), Qedge_detection
))
1689 tem
= XCDR (conversion
);
1691 x_edge_detection (f
, img
,
1692 Fplist_get (tem
, QCmatrix
),
1693 Fplist_get (tem
, QCcolor_adjustment
));
1699 /* Return the id of image with Lisp specification SPEC on frame F.
1700 SPEC must be a valid Lisp image specification (see valid_image_p). */
1703 lookup_image (struct frame
*f
, Lisp_Object spec
)
1708 /* F must be a window-system frame, and SPEC must be a valid image
1710 eassert (FRAME_WINDOW_P (f
));
1711 eassert (valid_image_p (spec
));
1713 /* Look up SPEC in the hash table of the image cache. */
1714 hash
= sxhash (spec
, 0);
1715 img
= search_image_cache (f
, spec
, hash
);
1716 if (img
&& img
->load_failed_p
)
1718 free_image (f
, img
);
1722 /* If not found, create a new image and cache it. */
1726 img
= make_image (spec
, hash
);
1727 cache_image (f
, img
);
1728 img
->load_failed_p
= img
->type
->load (f
, img
) == 0;
1729 img
->frame_foreground
= FRAME_FOREGROUND_PIXEL (f
);
1730 img
->frame_background
= FRAME_BACKGROUND_PIXEL (f
);
1732 /* If we can't load the image, and we don't have a width and
1733 height, use some arbitrary width and height so that we can
1734 draw a rectangle for it. */
1735 if (img
->load_failed_p
)
1739 value
= image_spec_value (spec
, QCwidth
, NULL
);
1740 img
->width
= (INTEGERP (value
)
1741 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
1742 value
= image_spec_value (spec
, QCheight
, NULL
);
1743 img
->height
= (INTEGERP (value
)
1744 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
1748 /* Handle image type independent image attributes
1749 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
1750 `:background COLOR'. */
1751 Lisp_Object ascent
, margin
, relief
, bg
;
1754 ascent
= image_spec_value (spec
, QCascent
, NULL
);
1755 if (INTEGERP (ascent
))
1756 img
->ascent
= XFASTINT (ascent
);
1757 else if (EQ (ascent
, Qcenter
))
1758 img
->ascent
= CENTERED_IMAGE_ASCENT
;
1760 margin
= image_spec_value (spec
, QCmargin
, NULL
);
1761 if (INTEGERP (margin
))
1762 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
1763 else if (CONSP (margin
))
1765 img
->hmargin
= XFASTINT (XCAR (margin
));
1766 img
->vmargin
= XFASTINT (XCDR (margin
));
1769 relief
= image_spec_value (spec
, QCrelief
, NULL
);
1770 relief_bound
= INT_MAX
- max (img
->hmargin
, img
->vmargin
);
1771 if (RANGED_INTEGERP (- relief_bound
, relief
, relief_bound
))
1773 img
->relief
= XINT (relief
);
1774 img
->hmargin
+= eabs (img
->relief
);
1775 img
->vmargin
+= eabs (img
->relief
);
1778 if (! img
->background_valid
)
1780 bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
1784 = x_alloc_image_color (f
, img
, bg
,
1785 FRAME_BACKGROUND_PIXEL (f
));
1786 img
->background_valid
= 1;
1790 /* Do image transformations and compute masks, unless we
1791 don't have the image yet. */
1792 if (!EQ (*img
->type
->type
, Qpostscript
))
1793 postprocess_image (f
, img
);
1799 /* We're using IMG, so set its timestamp to `now'. */
1800 EMACS_GET_TIME (img
->timestamp
);
1802 /* Value is the image id. */
1807 /* Cache image IMG in the image cache of frame F. */
1810 cache_image (struct frame
*f
, struct image
*img
)
1812 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1815 /* Find a free slot in c->images. */
1816 for (i
= 0; i
< c
->used
; ++i
)
1817 if (c
->images
[i
] == NULL
)
1820 /* If no free slot found, maybe enlarge c->images. */
1821 if (i
== c
->used
&& c
->used
== c
->size
)
1822 c
->images
= xpalloc (c
->images
, &c
->size
, 1, -1, sizeof *c
->images
);
1824 /* Add IMG to c->images, and assign IMG an id. */
1830 /* Add IMG to the cache's hash table. */
1831 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1832 img
->next
= c
->buckets
[i
];
1834 img
->next
->prev
= img
;
1836 c
->buckets
[i
] = img
;
1840 /* Call FN on every image in the image cache of frame F. Used to mark
1841 Lisp Objects in the image cache. */
1843 /* Mark Lisp objects in image IMG. */
1846 mark_image (struct image
*img
)
1848 mark_object (img
->spec
);
1849 mark_object (img
->dependencies
);
1851 if (!NILP (img
->lisp_data
))
1852 mark_object (img
->lisp_data
);
1857 mark_image_cache (struct image_cache
*c
)
1862 for (i
= 0; i
< c
->used
; ++i
)
1864 mark_image (c
->images
[i
]);
1870 /***********************************************************************
1871 X / NS / W32 support code
1872 ***********************************************************************/
1876 /* Macro for defining functions that will be loaded from image DLLs. */
1877 #define DEF_IMGLIB_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args
1879 /* Macro for loading those image functions from the library. */
1880 #define LOAD_IMGLIB_FN(lib,func) { \
1881 fn_##func = (void *) GetProcAddress (lib, #func); \
1882 if (!fn_##func) return 0; \
1885 #endif /* HAVE_NTGUI */
1887 static int x_create_x_image_and_pixmap (struct frame
*, int, int, int,
1888 XImagePtr
*, Pixmap
*);
1889 static void x_destroy_x_image (XImagePtr
);
1890 static void x_put_x_image (struct frame
*, XImagePtr
, Pixmap
, int, int);
1892 /* Return nonzero if XIMG's size WIDTH x HEIGHT doesn't break the
1894 WIDTH and HEIGHT must both be positive.
1895 If XIMG is null, assume it is a bitmap. */
1897 x_check_image_size (XImagePtr ximg
, int width
, int height
)
1899 #ifdef HAVE_X_WINDOWS
1900 /* Respect Xlib's limits: it cannot deal with images that have more
1901 than INT_MAX (and/or UINT_MAX) bytes. And respect Emacs's limits
1902 of PTRDIFF_MAX (and/or SIZE_MAX) bytes for any object. */
1905 XLIB_BYTES_MAX
= min (INT_MAX
, UINT_MAX
),
1906 X_IMAGE_BYTES_MAX
= min (XLIB_BYTES_MAX
, min (PTRDIFF_MAX
, SIZE_MAX
))
1909 int bitmap_pad
, depth
, bytes_per_line
;
1912 bitmap_pad
= ximg
->bitmap_pad
;
1913 depth
= ximg
->depth
;
1914 bytes_per_line
= ximg
->bytes_per_line
;
1920 bytes_per_line
= (width
>> 3) + ((width
& 7) != 0);
1922 return (width
<= (INT_MAX
- (bitmap_pad
- 1)) / depth
1923 && height
<= X_IMAGE_BYTES_MAX
/ bytes_per_line
);
1925 /* FIXME: Implement this check for the HAVE_NS and HAVE_NTGUI cases.
1926 For now, assume that every image size is allowed on these systems. */
1931 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
1932 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
1933 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
1934 via xmalloc. Print error messages via image_error if an error
1935 occurs. Value is non-zero if successful.
1937 On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
1938 should indicate the bit depth of the image. */
1941 x_create_x_image_and_pixmap (struct frame
*f
, int width
, int height
, int depth
,
1942 XImagePtr
*ximg
, Pixmap
*pixmap
)
1944 #ifdef HAVE_X_WINDOWS
1945 Display
*display
= FRAME_X_DISPLAY (f
);
1946 Window window
= FRAME_X_WINDOW (f
);
1947 Screen
*screen
= FRAME_X_SCREEN (f
);
1949 eassert (interrupt_input_blocked
);
1952 depth
= DefaultDepthOfScreen (screen
);
1953 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
1954 depth
, ZPixmap
, 0, NULL
, width
, height
,
1955 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
1958 image_error ("Unable to allocate X image", Qnil
, Qnil
);
1962 if (! x_check_image_size (*ximg
, width
, height
))
1964 x_destroy_x_image (*ximg
);
1966 image_error ("Image too large (%dx%d)",
1967 make_number (width
), make_number (height
));
1971 /* Allocate image raster. */
1972 (*ximg
)->data
= (char *) xmalloc ((*ximg
)->bytes_per_line
* height
);
1974 /* Allocate a pixmap of the same size. */
1975 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
1976 if (*pixmap
== NO_PIXMAP
)
1978 x_destroy_x_image (*ximg
);
1980 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
1985 #endif /* HAVE_X_WINDOWS */
1989 BITMAPINFOHEADER
*header
;
1991 int scanline_width_bits
;
1993 int palette_colors
= 0;
1998 if (depth
!= 1 && depth
!= 4 && depth
!= 8
1999 && depth
!= 16 && depth
!= 24 && depth
!= 32)
2001 image_error ("Invalid image bit depth specified", Qnil
, Qnil
);
2005 scanline_width_bits
= width
* depth
;
2006 remainder
= scanline_width_bits
% 32;
2009 scanline_width_bits
+= 32 - remainder
;
2011 /* Bitmaps with a depth less than 16 need a palette. */
2012 /* BITMAPINFO structure already contains the first RGBQUAD. */
2014 palette_colors
= 1 << (depth
- 1);
2016 *ximg
= xmalloc (sizeof (XImage
) + palette_colors
* sizeof (RGBQUAD
));
2018 header
= &(*ximg
)->info
.bmiHeader
;
2019 memset (&(*ximg
)->info
, 0, sizeof (BITMAPINFO
));
2020 header
->biSize
= sizeof (*header
);
2021 header
->biWidth
= width
;
2022 header
->biHeight
= -height
; /* negative indicates a top-down bitmap. */
2023 header
->biPlanes
= 1;
2024 header
->biBitCount
= depth
;
2025 header
->biCompression
= BI_RGB
;
2026 header
->biClrUsed
= palette_colors
;
2028 /* TODO: fill in palette. */
2031 (*ximg
)->info
.bmiColors
[0].rgbBlue
= 0;
2032 (*ximg
)->info
.bmiColors
[0].rgbGreen
= 0;
2033 (*ximg
)->info
.bmiColors
[0].rgbRed
= 0;
2034 (*ximg
)->info
.bmiColors
[0].rgbReserved
= 0;
2035 (*ximg
)->info
.bmiColors
[1].rgbBlue
= 255;
2036 (*ximg
)->info
.bmiColors
[1].rgbGreen
= 255;
2037 (*ximg
)->info
.bmiColors
[1].rgbRed
= 255;
2038 (*ximg
)->info
.bmiColors
[1].rgbReserved
= 0;
2041 hdc
= get_frame_dc (f
);
2043 /* Create a DIBSection and raster array for the bitmap,
2044 and store its handle in *pixmap. */
2045 *pixmap
= CreateDIBSection (hdc
, &((*ximg
)->info
),
2046 (depth
< 16) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
,
2047 /* casting avoids a GCC warning */
2048 (void **)&((*ximg
)->data
), NULL
, 0);
2050 /* Realize display palette and garbage all frames. */
2051 release_frame_dc (f
, hdc
);
2053 if (*pixmap
== NULL
)
2055 DWORD err
= GetLastError ();
2056 Lisp_Object errcode
;
2057 /* All system errors are < 10000, so the following is safe. */
2058 XSETINT (errcode
, err
);
2059 image_error ("Unable to create bitmap, error code %d", errcode
, Qnil
);
2060 x_destroy_x_image (*ximg
);
2066 #endif /* HAVE_NTGUI */
2069 *pixmap
= ns_image_for_XPM (width
, height
, depth
);
2073 image_error ("Unable to allocate NSImage for XPM pixmap", Qnil
, Qnil
);
2082 /* Destroy XImage XIMG. Free XIMG->data. */
2085 x_destroy_x_image (XImagePtr ximg
)
2087 eassert (interrupt_input_blocked
);
2090 #ifdef HAVE_X_WINDOWS
2093 XDestroyImage (ximg
);
2094 #endif /* HAVE_X_WINDOWS */
2096 /* Data will be freed by DestroyObject. */
2099 #endif /* HAVE_NTGUI */
2101 ns_release_object (ximg
);
2102 #endif /* HAVE_NS */
2107 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
2108 are width and height of both the image and pixmap. */
2111 x_put_x_image (struct frame
*f
, XImagePtr ximg
, Pixmap pixmap
, int width
, int height
)
2113 #ifdef HAVE_X_WINDOWS
2116 eassert (interrupt_input_blocked
);
2117 gc
= XCreateGC (FRAME_X_DISPLAY (f
), pixmap
, 0, NULL
);
2118 XPutImage (FRAME_X_DISPLAY (f
), pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
2119 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
2120 #endif /* HAVE_X_WINDOWS */
2123 #if 0 /* I don't think this is necessary looking at where it is used. */
2124 HDC hdc
= get_frame_dc (f
);
2125 SetDIBits (hdc
, pixmap
, 0, height
, ximg
->data
, &(ximg
->info
), DIB_RGB_COLORS
);
2126 release_frame_dc (f
, hdc
);
2128 #endif /* HAVE_NTGUI */
2131 eassert (ximg
== pixmap
);
2132 ns_retain_object (ximg
);
2137 /***********************************************************************
2139 ***********************************************************************/
2141 /* Find image file FILE. Look in data-directory/images, then
2142 x-bitmap-file-path. Value is the encoded full name of the file
2143 found, or nil if not found. */
2146 x_find_image_file (Lisp_Object file
)
2148 Lisp_Object file_found
, search_path
;
2151 /* TODO I think this should use something like image-load-path
2152 instead. Unfortunately, that can contain non-string elements. */
2153 search_path
= Fcons (Fexpand_file_name (build_string ("images"),
2155 Vx_bitmap_file_path
);
2157 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
2158 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
2164 file_found
= ENCODE_FILE (file_found
);
2172 /* Read FILE into memory. Value is a pointer to a buffer allocated
2173 with xmalloc holding FILE's contents. Value is null if an error
2174 occurred. *SIZE is set to the size of the file. */
2176 static unsigned char *
2177 slurp_file (char *file
, ptrdiff_t *size
)
2180 unsigned char *buf
= NULL
;
2183 if (stat (file
, &st
) == 0
2184 && (fp
= fopen (file
, "rb")) != NULL
2185 && 0 <= st
.st_size
&& st
.st_size
<= min (PTRDIFF_MAX
, SIZE_MAX
)
2186 && (buf
= (unsigned char *) xmalloc (st
.st_size
),
2187 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
2208 /***********************************************************************
2210 ***********************************************************************/
2212 static int xbm_scan (unsigned char **, unsigned char *, char *, int *);
2213 static int xbm_load (struct frame
*f
, struct image
*img
);
2214 static int xbm_load_image (struct frame
*f
, struct image
*img
,
2215 unsigned char *, unsigned char *);
2216 static int xbm_image_p (Lisp_Object object
);
2217 static int xbm_read_bitmap_data (struct frame
*f
,
2218 unsigned char *, unsigned char *,
2219 int *, int *, char **, int);
2220 static int xbm_file_p (Lisp_Object
);
2223 /* Indices of image specification fields in xbm_format, below. */
2225 enum xbm_keyword_index
2243 /* Vector of image_keyword structures describing the format
2244 of valid XBM image specifications. */
2246 static const struct image_keyword xbm_format
[XBM_LAST
] =
2248 {":type", IMAGE_SYMBOL_VALUE
, 1},
2249 {":file", IMAGE_STRING_VALUE
, 0},
2250 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2251 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2252 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2253 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
2254 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
2255 {":ascent", IMAGE_ASCENT_VALUE
, 0},
2256 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
2257 {":relief", IMAGE_INTEGER_VALUE
, 0},
2258 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2259 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2260 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
2263 /* Structure describing the image type XBM. */
2265 static struct image_type xbm_type
=
2274 /* Tokens returned from xbm_scan. */
2283 /* Return non-zero if OBJECT is a valid XBM-type image specification.
2284 A valid specification is a list starting with the symbol `image'
2285 The rest of the list is a property list which must contain an
2288 If the specification specifies a file to load, it must contain
2289 an entry `:file FILENAME' where FILENAME is a string.
2291 If the specification is for a bitmap loaded from memory it must
2292 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
2293 WIDTH and HEIGHT are integers > 0. DATA may be:
2295 1. a string large enough to hold the bitmap data, i.e. it must
2296 have a size >= (WIDTH + 7) / 8 * HEIGHT
2298 2. a bool-vector of size >= WIDTH * HEIGHT
2300 3. a vector of strings or bool-vectors, one for each line of the
2303 4. a string containing an in-memory XBM file. WIDTH and HEIGHT
2304 may not be specified in this case because they are defined in the
2307 Both the file and data forms may contain the additional entries
2308 `:background COLOR' and `:foreground COLOR'. If not present,
2309 foreground and background of the frame on which the image is
2310 displayed is used. */
2313 xbm_image_p (Lisp_Object object
)
2315 struct image_keyword kw
[XBM_LAST
];
2317 memcpy (kw
, xbm_format
, sizeof kw
);
2318 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
2321 eassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
2323 if (kw
[XBM_FILE
].count
)
2325 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
2328 else if (kw
[XBM_DATA
].count
&& xbm_file_p (kw
[XBM_DATA
].value
))
2330 /* In-memory XBM file. */
2331 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_FILE
].count
)
2339 /* Entries for `:width', `:height' and `:data' must be present. */
2340 if (!kw
[XBM_WIDTH
].count
2341 || !kw
[XBM_HEIGHT
].count
2342 || !kw
[XBM_DATA
].count
)
2345 data
= kw
[XBM_DATA
].value
;
2346 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
2347 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
2349 /* Check type of data, and width and height against contents of
2355 /* Number of elements of the vector must be >= height. */
2356 if (ASIZE (data
) < height
)
2359 /* Each string or bool-vector in data must be large enough
2360 for one line of the image. */
2361 for (i
= 0; i
< height
; ++i
)
2363 Lisp_Object elt
= AREF (data
, i
);
2368 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
2371 else if (BOOL_VECTOR_P (elt
))
2373 if (XBOOL_VECTOR (elt
)->size
< width
)
2380 else if (STRINGP (data
))
2383 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
2386 else if (BOOL_VECTOR_P (data
))
2388 if (XBOOL_VECTOR (data
)->size
/ height
< width
)
2399 /* Scan a bitmap file. FP is the stream to read from. Value is
2400 either an enumerator from enum xbm_token, or a character for a
2401 single-character token, or 0 at end of file. If scanning an
2402 identifier, store the lexeme of the identifier in SVAL. If
2403 scanning a number, store its value in *IVAL. */
2406 xbm_scan (unsigned char **s
, unsigned char *end
, char *sval
, int *ival
)
2412 /* Skip white space. */
2413 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
2418 else if (isdigit (c
))
2420 int value
= 0, digit
;
2422 if (c
== '0' && *s
< end
)
2425 if (c
== 'x' || c
== 'X')
2432 else if (c
>= 'a' && c
<= 'f')
2433 digit
= c
- 'a' + 10;
2434 else if (c
>= 'A' && c
<= 'F')
2435 digit
= c
- 'A' + 10;
2438 value
= 16 * value
+ digit
;
2441 else if (isdigit (c
))
2445 && (c
= *(*s
)++, isdigit (c
)))
2446 value
= 8 * value
+ c
- '0';
2453 && (c
= *(*s
)++, isdigit (c
)))
2454 value
= 10 * value
+ c
- '0';
2462 else if (isalpha (c
) || c
== '_')
2466 && (c
= *(*s
)++, (isalnum (c
) || c
== '_')))
2473 else if (c
== '/' && **s
== '*')
2475 /* C-style comment. */
2477 while (**s
&& (**s
!= '*' || *(*s
+ 1) != '/'))
2491 /* Create a Windows bitmap from X bitmap data. */
2493 w32_create_pixmap_from_bitmap_data (int width
, int height
, char *data
)
2495 static unsigned char swap_nibble
[16]
2496 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
2497 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
2498 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
2499 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
2501 unsigned char *bits
, *p
;
2504 w1
= (width
+ 7) / 8; /* nb of 8bits elt in X bitmap */
2505 w2
= ((width
+ 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
2506 bits
= (unsigned char *) alloca (height
* w2
);
2507 memset (bits
, 0, height
* w2
);
2508 for (i
= 0; i
< height
; i
++)
2511 for (j
= 0; j
< w1
; j
++)
2513 /* Bitswap XBM bytes to match how Windows does things. */
2514 unsigned char c
= *data
++;
2515 *p
++ = (unsigned char)((swap_nibble
[c
& 0xf] << 4)
2516 | (swap_nibble
[(c
>>4) & 0xf]));
2519 bmp
= CreateBitmap (width
, height
, 1, 1, (char *) bits
);
2525 convert_mono_to_color_image (struct frame
*f
, struct image
*img
,
2526 COLORREF foreground
, COLORREF background
)
2528 HDC hdc
, old_img_dc
, new_img_dc
;
2529 HGDIOBJ old_prev
, new_prev
;
2532 hdc
= get_frame_dc (f
);
2533 old_img_dc
= CreateCompatibleDC (hdc
);
2534 new_img_dc
= CreateCompatibleDC (hdc
);
2535 new_pixmap
= CreateCompatibleBitmap (hdc
, img
->width
, img
->height
);
2536 release_frame_dc (f
, hdc
);
2537 old_prev
= SelectObject (old_img_dc
, img
->pixmap
);
2538 new_prev
= SelectObject (new_img_dc
, new_pixmap
);
2539 /* Windows convention for mono bitmaps is black = background,
2540 white = foreground. */
2541 SetTextColor (new_img_dc
, background
);
2542 SetBkColor (new_img_dc
, foreground
);
2544 BitBlt (new_img_dc
, 0, 0, img
->width
, img
->height
, old_img_dc
,
2547 SelectObject (old_img_dc
, old_prev
);
2548 SelectObject (new_img_dc
, new_prev
);
2549 DeleteDC (old_img_dc
);
2550 DeleteDC (new_img_dc
);
2551 DeleteObject (img
->pixmap
);
2552 if (new_pixmap
== 0)
2553 fprintf (stderr
, "Failed to convert image to color.\n");
2555 img
->pixmap
= new_pixmap
;
2558 #define XBM_BIT_SHUFFLE(b) (~(b))
2562 #define XBM_BIT_SHUFFLE(b) (b)
2564 #endif /* HAVE_NTGUI */
2568 Create_Pixmap_From_Bitmap_Data (struct frame
*f
, struct image
*img
, char *data
,
2569 RGB_PIXEL_COLOR fg
, RGB_PIXEL_COLOR bg
,
2570 int non_default_colors
)
2574 = w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
, data
);
2576 /* If colors were specified, transfer the bitmap to a color one. */
2577 if (non_default_colors
)
2578 convert_mono_to_color_image (f
, img
, fg
, bg
);
2580 #elif defined (HAVE_NS)
2581 img
->pixmap
= ns_image_from_XBM (data
, img
->width
, img
->height
);
2585 (x_check_image_size (0, img
->width
, img
->height
)
2586 ? XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
2589 img
->width
, img
->height
,
2591 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)))
2593 #endif /* !HAVE_NTGUI && !HAVE_NS */
2598 /* Replacement for XReadBitmapFileData which isn't available under old
2599 X versions. CONTENTS is a pointer to a buffer to parse; END is the
2600 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
2601 the image. Return in *DATA the bitmap data allocated with xmalloc.
2602 Value is non-zero if successful. DATA null means just test if
2603 CONTENTS looks like an in-memory XBM file. If INHIBIT_IMAGE_ERROR
2604 is non-zero, inhibit the call to image_error when the image size is
2605 invalid (the bitmap remains unread). */
2608 xbm_read_bitmap_data (struct frame
*f
, unsigned char *contents
, unsigned char *end
,
2609 int *width
, int *height
, char **data
,
2610 int inhibit_image_error
)
2612 unsigned char *s
= contents
;
2613 char buffer
[BUFSIZ
];
2616 int bytes_per_line
, i
, nbytes
;
2622 LA1 = xbm_scan (&s, end, buffer, &value)
2624 #define expect(TOKEN) \
2625 if (LA1 != (TOKEN)) \
2630 #define expect_ident(IDENT) \
2631 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
2636 *width
= *height
= -1;
2639 LA1
= xbm_scan (&s
, end
, buffer
, &value
);
2641 /* Parse defines for width, height and hot-spots. */
2645 expect_ident ("define");
2646 expect (XBM_TK_IDENT
);
2648 if (LA1
== XBM_TK_NUMBER
)
2650 char *q
= strrchr (buffer
, '_');
2651 q
= q
? q
+ 1 : buffer
;
2652 if (strcmp (q
, "width") == 0)
2654 else if (strcmp (q
, "height") == 0)
2657 expect (XBM_TK_NUMBER
);
2660 if (!check_image_size (f
, *width
, *height
))
2662 if (!inhibit_image_error
)
2663 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
2666 else if (data
== NULL
)
2669 /* Parse bits. Must start with `static'. */
2670 expect_ident ("static");
2671 if (LA1
== XBM_TK_IDENT
)
2673 if (strcmp (buffer
, "unsigned") == 0)
2676 expect_ident ("char");
2678 else if (strcmp (buffer
, "short") == 0)
2682 if (*width
% 16 && *width
% 16 < 9)
2685 else if (strcmp (buffer
, "char") == 0)
2693 expect (XBM_TK_IDENT
);
2699 if (! x_check_image_size (0, *width
, *height
))
2701 if (!inhibit_image_error
)
2702 image_error ("Image too large (%dx%d)",
2703 make_number (*width
), make_number (*height
));
2706 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
2707 nbytes
= bytes_per_line
* *height
;
2708 p
= *data
= (char *) xmalloc (nbytes
);
2712 for (i
= 0; i
< nbytes
; i
+= 2)
2715 expect (XBM_TK_NUMBER
);
2717 *p
++ = XBM_BIT_SHUFFLE (val
);
2718 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
2719 *p
++ = XBM_BIT_SHUFFLE (value
>> 8);
2721 if (LA1
== ',' || LA1
== '}')
2729 for (i
= 0; i
< nbytes
; ++i
)
2732 expect (XBM_TK_NUMBER
);
2734 *p
++ = XBM_BIT_SHUFFLE (val
);
2736 if (LA1
== ',' || LA1
== '}')
2761 /* Load XBM image IMG which will be displayed on frame F from buffer
2762 CONTENTS. END is the end of the buffer. Value is non-zero if
2766 xbm_load_image (struct frame
*f
, struct image
*img
, unsigned char *contents
,
2773 rc
= xbm_read_bitmap_data (f
, contents
, end
, &img
->width
, &img
->height
,
2777 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2778 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2779 int non_default_colors
= 0;
2782 eassert (img
->width
> 0 && img
->height
> 0);
2784 /* Get foreground and background colors, maybe allocate colors. */
2785 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
2788 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
2789 non_default_colors
= 1;
2791 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
2794 background
= x_alloc_image_color (f
, img
, value
, background
);
2795 img
->background
= background
;
2796 img
->background_valid
= 1;
2797 non_default_colors
= 1;
2800 Create_Pixmap_From_Bitmap_Data (f
, img
, data
,
2801 foreground
, background
,
2802 non_default_colors
);
2805 if (img
->pixmap
== NO_PIXMAP
)
2807 x_clear_image (f
, img
);
2808 image_error ("Unable to create X pixmap for `%s'", img
->spec
, Qnil
);
2814 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
2820 /* Value is non-zero if DATA looks like an in-memory XBM file. */
2823 xbm_file_p (Lisp_Object data
)
2826 return (STRINGP (data
)
2827 && xbm_read_bitmap_data (NULL
, SDATA (data
),
2828 (SDATA (data
) + SBYTES (data
)),
2833 /* Fill image IMG which is used on frame F with pixmap data. Value is
2834 non-zero if successful. */
2837 xbm_load (struct frame
*f
, struct image
*img
)
2840 Lisp_Object file_name
;
2842 eassert (xbm_image_p (img
->spec
));
2844 /* If IMG->spec specifies a file name, create a non-file spec from it. */
2845 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
2846 if (STRINGP (file_name
))
2849 unsigned char *contents
;
2852 file
= x_find_image_file (file_name
);
2853 if (!STRINGP (file
))
2855 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
2859 contents
= slurp_file (SSDATA (file
), &size
);
2860 if (contents
== NULL
)
2862 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
2866 success_p
= xbm_load_image (f
, img
, contents
, contents
+ size
);
2871 struct image_keyword fmt
[XBM_LAST
];
2873 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2874 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2875 int non_default_colors
= 0;
2878 int in_memory_file_p
= 0;
2880 /* See if data looks like an in-memory XBM file. */
2881 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
2882 in_memory_file_p
= xbm_file_p (data
);
2884 /* Parse the image specification. */
2885 memcpy (fmt
, xbm_format
, sizeof fmt
);
2886 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 eassert (img
->width
> 0 && img
->height
> 0);
2896 if (!check_image_size (f
, img
->width
, img
->height
))
2898 image_error ("Invalid image size (see `max-image-size')",
2904 /* Get foreground and background colors, maybe allocate colors. */
2905 if (fmt
[XBM_FOREGROUND
].count
2906 && STRINGP (fmt
[XBM_FOREGROUND
].value
))
2908 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
2910 non_default_colors
= 1;
2913 if (fmt
[XBM_BACKGROUND
].count
2914 && STRINGP (fmt
[XBM_BACKGROUND
].value
))
2916 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
2918 non_default_colors
= 1;
2921 if (in_memory_file_p
)
2922 success_p
= xbm_load_image (f
, img
, SDATA (data
),
2931 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
2933 p
= bits
= (char *) alloca (nbytes
* img
->height
);
2934 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
2936 Lisp_Object line
= AREF (data
, i
);
2938 memcpy (p
, SDATA (line
), nbytes
);
2940 memcpy (p
, XBOOL_VECTOR (line
)->data
, nbytes
);
2943 else if (STRINGP (data
))
2944 bits
= SSDATA (data
);
2946 bits
= (char *) XBOOL_VECTOR (data
)->data
;
2952 /* Windows mono bitmaps are reversed compared with X. */
2953 invertedBits
= bits
;
2954 nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
2956 bits
= (char *) alloca (nbytes
);
2957 for (i
= 0; i
< nbytes
; i
++)
2958 bits
[i
] = XBM_BIT_SHUFFLE (invertedBits
[i
]);
2961 /* Create the pixmap. */
2963 if (x_check_image_size (0, img
->width
, img
->height
))
2964 Create_Pixmap_From_Bitmap_Data (f
, img
, bits
,
2965 foreground
, background
,
2966 non_default_colors
);
2968 img
->pixmap
= NO_PIXMAP
;
2974 image_error ("Unable to create pixmap for XBM image `%s'",
2976 x_clear_image (f
, img
);
2986 /***********************************************************************
2988 ***********************************************************************/
2990 #if defined (HAVE_XPM) || defined (HAVE_NS)
2992 static int xpm_image_p (Lisp_Object object
);
2993 static int xpm_load (struct frame
*f
, struct image
*img
);
2994 static int xpm_valid_color_symbols_p (Lisp_Object
);
2996 #endif /* HAVE_XPM || HAVE_NS */
3000 /* Indicate to xpm.h that we don't have Xlib. */
3002 /* simx.h in xpm defines XColor and XImage differently than Emacs. */
3003 /* It also defines Display the same way as Emacs, but gcc 3.3 still barfs. */
3004 #define XColor xpm_XColor
3005 #define XImage xpm_XImage
3006 #define Display xpm_Display
3007 #define PIXEL_ALREADY_TYPEDEFED
3008 #include "X11/xpm.h"
3013 #undef PIXEL_ALREADY_TYPEDEFED
3015 #include "X11/xpm.h"
3016 #endif /* HAVE_NTGUI */
3017 #endif /* HAVE_XPM */
3019 #if defined (HAVE_XPM) || defined (HAVE_NS)
3020 /* The symbol `xpm' identifying XPM-format images. */
3022 static Lisp_Object Qxpm
;
3024 /* Indices of image specification fields in xpm_format, below. */
3026 enum xpm_keyword_index
3042 /* Vector of image_keyword structures describing the format
3043 of valid XPM image specifications. */
3045 static const struct image_keyword xpm_format
[XPM_LAST
] =
3047 {":type", IMAGE_SYMBOL_VALUE
, 1},
3048 {":file", IMAGE_STRING_VALUE
, 0},
3049 {":data", IMAGE_STRING_VALUE
, 0},
3050 {":ascent", IMAGE_ASCENT_VALUE
, 0},
3051 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
3052 {":relief", IMAGE_INTEGER_VALUE
, 0},
3053 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3054 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3055 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3056 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3057 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
3060 /* Structure describing the image type XPM. */
3062 static struct image_type xpm_type
=
3071 #ifdef HAVE_X_WINDOWS
3073 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
3074 functions for allocating image colors. Our own functions handle
3075 color allocation failures more gracefully than the ones on the XPM
3078 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
3079 #define ALLOC_XPM_COLORS
3081 #endif /* HAVE_X_WINDOWS */
3083 #ifdef ALLOC_XPM_COLORS
3085 static void xpm_init_color_cache (struct frame
*, XpmAttributes
*);
3086 static void xpm_free_color_cache (void);
3087 static int xpm_lookup_color (struct frame
*, char *, XColor
*);
3088 static int xpm_color_bucket (char *);
3089 static struct xpm_cached_color
*xpm_cache_color (struct frame
*, char *,
3092 /* An entry in a hash table used to cache color definitions of named
3093 colors. This cache is necessary to speed up XPM image loading in
3094 case we do color allocations ourselves. Without it, we would need
3095 a call to XParseColor per pixel in the image. */
3097 struct xpm_cached_color
3099 /* Next in collision chain. */
3100 struct xpm_cached_color
*next
;
3102 /* Color definition (RGB and pixel color). */
3109 /* The hash table used for the color cache, and its bucket vector
3112 #define XPM_COLOR_CACHE_BUCKETS 1001
3113 static struct xpm_cached_color
**xpm_color_cache
;
3115 /* Initialize the color cache. */
3118 xpm_init_color_cache (struct frame
*f
, XpmAttributes
*attrs
)
3120 size_t nbytes
= XPM_COLOR_CACHE_BUCKETS
* sizeof *xpm_color_cache
;
3121 xpm_color_cache
= (struct xpm_cached_color
**) xmalloc (nbytes
);
3122 memset (xpm_color_cache
, 0, nbytes
);
3123 init_color_table ();
3125 if (attrs
->valuemask
& XpmColorSymbols
)
3130 for (i
= 0; i
< attrs
->numsymbols
; ++i
)
3131 if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
3132 attrs
->colorsymbols
[i
].value
, &color
))
3134 color
.pixel
= lookup_rgb_color (f
, color
.red
, color
.green
,
3136 xpm_cache_color (f
, attrs
->colorsymbols
[i
].name
, &color
, -1);
3141 /* Free the color cache. */
3144 xpm_free_color_cache (void)
3146 struct xpm_cached_color
*p
, *next
;
3149 for (i
= 0; i
< XPM_COLOR_CACHE_BUCKETS
; ++i
)
3150 for (p
= xpm_color_cache
[i
]; p
; p
= next
)
3156 xfree (xpm_color_cache
);
3157 xpm_color_cache
= NULL
;
3158 free_color_table ();
3161 /* Return the bucket index for color named COLOR_NAME in the color
3165 xpm_color_bucket (char *color_name
)
3167 EMACS_UINT hash
= hash_string (color_name
, strlen (color_name
));
3168 return hash
% XPM_COLOR_CACHE_BUCKETS
;
3172 /* On frame F, cache values COLOR for color with name COLOR_NAME.
3173 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
3176 static struct xpm_cached_color
*
3177 xpm_cache_color (struct frame
*f
, char *color_name
, XColor
*color
, int bucket
)
3180 struct xpm_cached_color
*p
;
3183 bucket
= xpm_color_bucket (color_name
);
3185 nbytes
= offsetof (struct xpm_cached_color
, name
) + strlen (color_name
) + 1;
3186 p
= (struct xpm_cached_color
*) xmalloc (nbytes
);
3187 strcpy (p
->name
, color_name
);
3189 p
->next
= xpm_color_cache
[bucket
];
3190 xpm_color_cache
[bucket
] = p
;
3194 /* Look up color COLOR_NAME for frame F in the color cache. If found,
3195 return the cached definition in *COLOR. Otherwise, make a new
3196 entry in the cache and allocate the color. Value is zero if color
3197 allocation failed. */
3200 xpm_lookup_color (struct frame
*f
, char *color_name
, XColor
*color
)
3202 struct xpm_cached_color
*p
;
3203 int h
= xpm_color_bucket (color_name
);
3205 for (p
= xpm_color_cache
[h
]; p
; p
= p
->next
)
3206 if (strcmp (p
->name
, color_name
) == 0)
3211 else if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
3214 color
->pixel
= lookup_rgb_color (f
, color
->red
, color
->green
,
3216 p
= xpm_cache_color (f
, color_name
, color
, h
);
3218 /* You get `opaque' at least from ImageMagick converting pbm to xpm
3219 with transparency, and it's useful. */
3220 else if (strcmp ("opaque", color_name
) == 0)
3222 memset (color
, 0, sizeof (XColor
)); /* Is this necessary/correct? */
3223 color
->pixel
= FRAME_FOREGROUND_PIXEL (f
);
3224 p
= xpm_cache_color (f
, color_name
, color
, h
);
3231 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
3232 CLOSURE is a pointer to the frame on which we allocate the
3233 color. Return in *COLOR the allocated color. Value is non-zero
3237 xpm_alloc_color (Display
*dpy
, Colormap cmap
, char *color_name
, XColor
*color
,
3240 return xpm_lookup_color ((struct frame
*) closure
, color_name
, color
);
3244 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
3245 is a pointer to the frame on which we allocate the color. Value is
3246 non-zero if successful. */
3249 xpm_free_colors (Display
*dpy
, Colormap cmap
, Pixel
*pixels
, int npixels
, void *closure
)
3254 #endif /* ALLOC_XPM_COLORS */
3259 /* XPM library details. */
3261 DEF_IMGLIB_FN (void, XpmFreeAttributes
, (XpmAttributes
*));
3262 DEF_IMGLIB_FN (int, XpmCreateImageFromBuffer
, (Display
*, char *, xpm_XImage
**,
3263 xpm_XImage
**, XpmAttributes
*));
3264 DEF_IMGLIB_FN (int, XpmReadFileToImage
, (Display
*, char *, xpm_XImage
**,
3265 xpm_XImage
**, XpmAttributes
*));
3266 DEF_IMGLIB_FN (void, XImageFree
, (xpm_XImage
*));
3269 init_xpm_functions (Lisp_Object libraries
)
3273 if (!(library
= w32_delayed_load (libraries
, Qxpm
)))
3276 LOAD_IMGLIB_FN (library
, XpmFreeAttributes
);
3277 LOAD_IMGLIB_FN (library
, XpmCreateImageFromBuffer
);
3278 LOAD_IMGLIB_FN (library
, XpmReadFileToImage
);
3279 LOAD_IMGLIB_FN (library
, XImageFree
);
3283 #endif /* HAVE_NTGUI */
3286 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
3287 for XPM images. Such a list must consist of conses whose car and
3291 xpm_valid_color_symbols_p (Lisp_Object color_symbols
)
3293 while (CONSP (color_symbols
))
3295 Lisp_Object sym
= XCAR (color_symbols
);
3297 || !STRINGP (XCAR (sym
))
3298 || !STRINGP (XCDR (sym
)))
3300 color_symbols
= XCDR (color_symbols
);
3303 return NILP (color_symbols
);
3307 /* Value is non-zero if OBJECT is a valid XPM image specification. */
3310 xpm_image_p (Lisp_Object object
)
3312 struct image_keyword fmt
[XPM_LAST
];
3313 memcpy (fmt
, xpm_format
, sizeof fmt
);
3314 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
3315 /* Either `:file' or `:data' must be present. */
3316 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
3317 /* Either no `:color-symbols' or it's a list of conses
3318 whose car and cdr are strings. */
3319 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
3320 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
)));
3323 #endif /* HAVE_XPM || HAVE_NS */
3325 #if defined HAVE_XPM && defined HAVE_X_WINDOWS && !defined USE_GTK
3327 x_create_bitmap_from_xpm_data (struct frame
*f
, const char **bits
)
3329 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3332 XpmAttributes attrs
;
3333 Pixmap bitmap
, mask
;
3335 memset (&attrs
, 0, sizeof attrs
);
3337 attrs
.visual
= FRAME_X_VISUAL (f
);
3338 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3339 attrs
.valuemask
|= XpmVisual
;
3340 attrs
.valuemask
|= XpmColormap
;
3342 rc
= XpmCreatePixmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3343 (char **) bits
, &bitmap
, &mask
, &attrs
);
3344 if (rc
!= XpmSuccess
)
3346 XpmFreeAttributes (&attrs
);
3350 id
= x_allocate_bitmap_record (f
);
3351 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
3352 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
3353 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
3354 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
3355 dpyinfo
->bitmaps
[id
- 1].height
= attrs
.height
;
3356 dpyinfo
->bitmaps
[id
- 1].width
= attrs
.width
;
3357 dpyinfo
->bitmaps
[id
- 1].depth
= attrs
.depth
;
3358 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
3360 XpmFreeAttributes (&attrs
);
3363 #endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */
3365 /* Load image IMG which will be displayed on frame F. Value is
3366 non-zero if successful. */
3371 xpm_load (struct frame
*f
, struct image
*img
)
3374 XpmAttributes attrs
;
3375 Lisp_Object specified_file
, color_symbols
;
3378 xpm_XImage
* xpm_image
= NULL
, * xpm_mask
= NULL
;
3379 #endif /* HAVE_NTGUI */
3381 /* Configure the XPM lib. Use the visual of frame F. Allocate
3382 close colors. Return colors allocated. */
3383 memset (&attrs
, 0, sizeof attrs
);
3386 attrs
.visual
= FRAME_X_VISUAL (f
);
3387 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3388 attrs
.valuemask
|= XpmVisual
;
3389 attrs
.valuemask
|= XpmColormap
;
3390 #endif /* HAVE_NTGUI */
3392 #ifdef ALLOC_XPM_COLORS
3393 /* Allocate colors with our own functions which handle
3394 failing color allocation more gracefully. */
3395 attrs
.color_closure
= f
;
3396 attrs
.alloc_color
= xpm_alloc_color
;
3397 attrs
.free_colors
= xpm_free_colors
;
3398 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
3399 #else /* not ALLOC_XPM_COLORS */
3400 /* Let the XPM lib allocate colors. */
3401 attrs
.valuemask
|= XpmReturnAllocPixels
;
3402 #ifdef XpmAllocCloseColors
3403 attrs
.alloc_close_colors
= 1;
3404 attrs
.valuemask
|= XpmAllocCloseColors
;
3405 #else /* not XpmAllocCloseColors */
3406 attrs
.closeness
= 600;
3407 attrs
.valuemask
|= XpmCloseness
;
3408 #endif /* not XpmAllocCloseColors */
3409 #endif /* ALLOC_XPM_COLORS */
3411 /* If image specification contains symbolic color definitions, add
3412 these to `attrs'. */
3413 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
3414 if (CONSP (color_symbols
))
3417 XpmColorSymbol
*xpm_syms
;
3420 attrs
.valuemask
|= XpmColorSymbols
;
3422 /* Count number of symbols. */
3423 attrs
.numsymbols
= 0;
3424 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
3427 /* Allocate an XpmColorSymbol array. */
3428 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
3429 xpm_syms
= (XpmColorSymbol
*) alloca (size
);
3430 memset (xpm_syms
, 0, size
);
3431 attrs
.colorsymbols
= xpm_syms
;
3433 /* Fill the color symbol array. */
3434 for (tail
= color_symbols
, i
= 0;
3436 ++i
, tail
= XCDR (tail
))
3440 char *empty_string
= (char *) "";
3442 if (!CONSP (XCAR (tail
)))
3444 xpm_syms
[i
].name
= empty_string
;
3445 xpm_syms
[i
].value
= empty_string
;
3448 name
= XCAR (XCAR (tail
));
3449 color
= XCDR (XCAR (tail
));
3452 xpm_syms
[i
].name
= (char *) alloca (SCHARS (name
) + 1);
3453 strcpy (xpm_syms
[i
].name
, SSDATA (name
));
3456 xpm_syms
[i
].name
= empty_string
;
3457 if (STRINGP (color
))
3459 xpm_syms
[i
].value
= (char *) alloca (SCHARS (color
) + 1);
3460 strcpy (xpm_syms
[i
].value
, SSDATA (color
));
3463 xpm_syms
[i
].value
= empty_string
;
3467 /* Create a pixmap for the image, either from a file, or from a
3468 string buffer containing data in the same format as an XPM file. */
3469 #ifdef ALLOC_XPM_COLORS
3470 xpm_init_color_cache (f
, &attrs
);
3473 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
3477 HDC frame_dc
= get_frame_dc (f
);
3478 hdc
= CreateCompatibleDC (frame_dc
);
3479 release_frame_dc (f
, frame_dc
);
3481 #endif /* HAVE_NTGUI */
3483 if (STRINGP (specified_file
))
3485 Lisp_Object file
= x_find_image_file (specified_file
);
3486 if (!STRINGP (file
))
3488 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
3489 #ifdef ALLOC_XPM_COLORS
3490 xpm_free_color_cache ();
3496 /* XpmReadFileToPixmap is not available in the Windows port of
3497 libxpm. But XpmReadFileToImage almost does what we want. */
3498 rc
= fn_XpmReadFileToImage (&hdc
, SDATA (file
),
3499 &xpm_image
, &xpm_mask
,
3502 rc
= XpmReadFileToPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3503 SSDATA (file
), &img
->pixmap
, &img
->mask
,
3505 #endif /* HAVE_NTGUI */
3509 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
3510 if (!STRINGP (buffer
))
3512 image_error ("Invalid image data `%s'", buffer
, Qnil
);
3513 #ifdef ALLOC_XPM_COLORS
3514 xpm_free_color_cache ();
3519 /* XpmCreatePixmapFromBuffer is not available in the Windows port
3520 of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
3521 rc
= fn_XpmCreateImageFromBuffer (&hdc
, SDATA (buffer
),
3522 &xpm_image
, &xpm_mask
,
3525 rc
= XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3527 &img
->pixmap
, &img
->mask
,
3529 #endif /* HAVE_NTGUI */
3532 if (rc
== XpmSuccess
)
3534 #if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS)
3535 img
->colors
= colors_in_color_table (&img
->ncolors
);
3536 #else /* not ALLOC_XPM_COLORS */
3540 /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
3541 plus some duplicate attributes. */
3542 if (xpm_image
&& xpm_image
->bitmap
)
3544 img
->pixmap
= xpm_image
->bitmap
;
3545 /* XImageFree in libXpm frees XImage struct without destroying
3546 the bitmap, which is what we want. */
3547 fn_XImageFree (xpm_image
);
3549 if (xpm_mask
&& xpm_mask
->bitmap
)
3551 /* The mask appears to be inverted compared with what we expect.
3552 TODO: invert our expectations. See other places where we
3553 have to invert bits because our idea of masks is backwards. */
3555 old_obj
= SelectObject (hdc
, xpm_mask
->bitmap
);
3557 PatBlt (hdc
, 0, 0, xpm_mask
->width
, xpm_mask
->height
, DSTINVERT
);
3558 SelectObject (hdc
, old_obj
);
3560 img
->mask
= xpm_mask
->bitmap
;
3561 fn_XImageFree (xpm_mask
);
3566 #endif /* HAVE_NTGUI */
3568 /* Remember allocated colors. */
3569 img
->colors
= xnmalloc (attrs
.nalloc_pixels
, sizeof *img
->colors
);
3570 img
->ncolors
= attrs
.nalloc_pixels
;
3571 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
3573 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
3574 #ifdef DEBUG_X_COLORS
3575 register_color (img
->colors
[i
]);
3578 #endif /* not ALLOC_XPM_COLORS */
3580 img
->width
= attrs
.width
;
3581 img
->height
= attrs
.height
;
3582 eassert (img
->width
> 0 && img
->height
> 0);
3584 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
3586 fn_XpmFreeAttributes (&attrs
);
3588 XpmFreeAttributes (&attrs
);
3589 #endif /* HAVE_NTGUI */
3595 #endif /* HAVE_NTGUI */
3600 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
3603 case XpmFileInvalid
:
3604 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
3608 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
3611 case XpmColorFailed
:
3612 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
3616 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
3621 #ifdef ALLOC_XPM_COLORS
3622 xpm_free_color_cache ();
3624 return rc
== XpmSuccess
;
3627 #endif /* HAVE_XPM */
3629 #if defined (HAVE_NS) && !defined (HAVE_XPM)
3631 /* XPM support functions for NS where libxpm is not available.
3632 Only XPM version 3 (without any extensions) is supported. */
3634 static void xpm_put_color_table_v (Lisp_Object
, const unsigned char *,
3636 static Lisp_Object
xpm_get_color_table_v (Lisp_Object
,
3637 const unsigned char *, int);
3638 static void xpm_put_color_table_h (Lisp_Object
, const unsigned char *,
3640 static Lisp_Object
xpm_get_color_table_h (Lisp_Object
,
3641 const unsigned char *, int);
3643 /* Tokens returned from xpm_scan. */
3652 /* Scan an XPM data and return a character (< 256) or a token defined
3653 by enum xpm_token above. *S and END are the start (inclusive) and
3654 the end (exclusive) addresses of the data, respectively. Advance
3655 *S while scanning. If token is either XPM_TK_IDENT or
3656 XPM_TK_STRING, *BEG and *LEN are set to the start address and the
3657 length of the corresponding token, respectively. */
3660 xpm_scan (const unsigned char **s
,
3661 const unsigned char *end
,
3662 const unsigned char **beg
,
3669 /* Skip white-space. */
3670 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
3673 /* gnus-pointer.xpm uses '-' in its identifier.
3674 sb-dir-plus.xpm uses '+' in its identifier. */
3675 if (isalpha (c
) || c
== '_' || c
== '-' || c
== '+')
3679 && (c
= **s
, isalnum (c
) || c
== '_' || c
== '-' || c
== '+'))
3682 return XPM_TK_IDENT
;
3687 while (*s
< end
&& **s
!= '"')
3692 return XPM_TK_STRING
;
3696 if (*s
< end
&& **s
== '*')
3698 /* C-style comment. */
3702 while (*s
< end
&& *(*s
)++ != '*')
3705 while (*s
< end
&& **s
!= '/');
3719 /* Functions for color table lookup in XPM data. A key is a string
3720 specifying the color of each pixel in XPM data. A value is either
3721 an integer that specifies a pixel color, Qt that specifies
3722 transparency, or Qnil for the unspecified color. If the length of
3723 the key string is one, a vector is used as a table. Otherwise, a
3724 hash table is used. */
3727 xpm_make_color_table_v (void (**put_func
) (Lisp_Object
,
3728 const unsigned char *,
3731 Lisp_Object (**get_func
) (Lisp_Object
,
3732 const unsigned char *,
3735 *put_func
= xpm_put_color_table_v
;
3736 *get_func
= xpm_get_color_table_v
;
3737 return Fmake_vector (make_number (256), Qnil
);
3741 xpm_put_color_table_v (Lisp_Object color_table
,
3742 const unsigned char *chars_start
,
3746 ASET (color_table
, *chars_start
, color
);
3750 xpm_get_color_table_v (Lisp_Object color_table
,
3751 const unsigned char *chars_start
,
3754 return AREF (color_table
, *chars_start
);
3758 xpm_make_color_table_h (void (**put_func
) (Lisp_Object
,
3759 const unsigned char *,
3762 Lisp_Object (**get_func
) (Lisp_Object
,
3763 const unsigned char *,
3766 *put_func
= xpm_put_color_table_h
;
3767 *get_func
= xpm_get_color_table_h
;
3768 return make_hash_table (Qequal
, make_number (DEFAULT_HASH_SIZE
),
3769 make_float (DEFAULT_REHASH_SIZE
),
3770 make_float (DEFAULT_REHASH_THRESHOLD
),
3775 xpm_put_color_table_h (Lisp_Object color_table
,
3776 const unsigned char *chars_start
,
3780 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
3781 EMACS_UINT hash_code
;
3782 Lisp_Object chars
= make_unibyte_string (chars_start
, chars_len
);
3784 hash_lookup (table
, chars
, &hash_code
);
3785 hash_put (table
, chars
, color
, hash_code
);
3789 xpm_get_color_table_h (Lisp_Object color_table
,
3790 const unsigned char *chars_start
,
3793 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
3795 hash_lookup (table
, make_unibyte_string (chars_start
, chars_len
), NULL
);
3797 return i
>= 0 ? HASH_VALUE (table
, i
) : Qnil
;
3800 enum xpm_color_key
{
3808 static const char xpm_color_key_strings
[][4] = {"s", "m", "g4", "g", "c"};
3811 xpm_str_to_color_key (const char *s
)
3816 i
< sizeof xpm_color_key_strings
/ sizeof xpm_color_key_strings
[0];
3818 if (strcmp (xpm_color_key_strings
[i
], s
) == 0)
3824 xpm_load_image (struct frame
*f
,
3826 const unsigned char *contents
,
3827 const unsigned char *end
)
3829 const unsigned char *s
= contents
, *beg
, *str
;
3830 unsigned char buffer
[BUFSIZ
];
3831 int width
, height
, x
, y
;
3832 int num_colors
, chars_per_pixel
;
3835 void (*put_color_table
) (Lisp_Object
, const unsigned char *, int, Lisp_Object
);
3836 Lisp_Object (*get_color_table
) (Lisp_Object
, const unsigned char *, int);
3837 Lisp_Object frame
, color_symbols
, color_table
;
3838 int best_key
, have_mask
= 0;
3839 XImagePtr ximg
= NULL
, mask_img
= NULL
;
3842 LA1 = xpm_scan (&s, end, &beg, &len)
3844 #define expect(TOKEN) \
3845 if (LA1 != (TOKEN)) \
3850 #define expect_ident(IDENT) \
3851 if (LA1 == XPM_TK_IDENT \
3852 && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
3857 if (!(end
- s
>= 9 && memcmp (s
, "/* XPM */", 9) == 0))
3861 expect_ident ("static");
3862 expect_ident ("char");
3864 expect (XPM_TK_IDENT
);
3869 expect (XPM_TK_STRING
);
3872 memcpy (buffer
, beg
, len
);
3874 if (sscanf (buffer
, "%d %d %d %d", &width
, &height
,
3875 &num_colors
, &chars_per_pixel
) != 4
3876 || width
<= 0 || height
<= 0
3877 || num_colors
<= 0 || chars_per_pixel
<= 0)
3880 if (!check_image_size (f
, width
, height
))
3882 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
3886 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
3887 &ximg
, &img
->pixmap
)
3889 || !x_create_x_image_and_pixmap (f
, width
, height
, 1,
3890 &mask_img
, &img
->mask
)
3894 image_error ("Image too large", Qnil
, Qnil
);
3900 XSETFRAME (frame
, f
);
3901 if (!NILP (Fxw_display_color_p (frame
)))
3902 best_key
= XPM_COLOR_KEY_C
;
3903 else if (!NILP (Fx_display_grayscale_p (frame
)))
3904 best_key
= (XFASTINT (Fx_display_planes (frame
)) > 2
3905 ? XPM_COLOR_KEY_G
: XPM_COLOR_KEY_G4
);
3907 best_key
= XPM_COLOR_KEY_M
;
3909 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
3910 if (chars_per_pixel
== 1)
3911 color_table
= xpm_make_color_table_v (&put_color_table
,
3914 color_table
= xpm_make_color_table_h (&put_color_table
,
3917 while (num_colors
-- > 0)
3919 char *color
, *max_color
;
3920 int key
, next_key
, max_key
= 0;
3921 Lisp_Object symbol_color
= Qnil
, color_val
;
3924 expect (XPM_TK_STRING
);
3925 if (len
<= chars_per_pixel
|| len
>= BUFSIZ
+ chars_per_pixel
)
3927 memcpy (buffer
, beg
+ chars_per_pixel
, len
- chars_per_pixel
);
3928 buffer
[len
- chars_per_pixel
] = '\0';
3930 str
= strtok (buffer
, " \t");
3933 key
= xpm_str_to_color_key (str
);
3938 color
= strtok (NULL
, " \t");
3942 while ((str
= strtok (NULL
, " \t")) != NULL
)
3944 next_key
= xpm_str_to_color_key (str
);
3947 color
[strlen (color
)] = ' ';
3950 if (key
== XPM_COLOR_KEY_S
)
3952 if (NILP (symbol_color
))
3953 symbol_color
= build_string (color
);
3955 else if (max_key
< key
&& key
<= best_key
)
3965 if (!NILP (color_symbols
) && !NILP (symbol_color
))
3967 Lisp_Object specified_color
= Fassoc (symbol_color
, color_symbols
);
3969 if (CONSP (specified_color
) && STRINGP (XCDR (specified_color
)))
3971 if (xstrcasecmp (SSDATA (XCDR (specified_color
)), "None") == 0)
3973 else if (x_defined_color (f
, SDATA (XCDR (specified_color
)),
3975 color_val
= make_number (cdef
.pixel
);
3978 if (NILP (color_val
) && max_key
> 0)
3980 if (xstrcasecmp (max_color
, "None") == 0)
3982 else if (x_defined_color (f
, max_color
, &cdef
, 0))
3983 color_val
= make_number (cdef
.pixel
);
3985 if (!NILP (color_val
))
3986 (*put_color_table
) (color_table
, beg
, chars_per_pixel
, color_val
);
3991 for (y
= 0; y
< height
; y
++)
3993 expect (XPM_TK_STRING
);
3995 if (len
< width
* chars_per_pixel
)
3997 for (x
= 0; x
< width
; x
++, str
+= chars_per_pixel
)
3999 Lisp_Object color_val
=
4000 (*get_color_table
) (color_table
, str
, chars_per_pixel
);
4002 XPutPixel (ximg
, x
, y
,
4003 (INTEGERP (color_val
) ? XINT (color_val
)
4004 : FRAME_FOREGROUND_PIXEL (f
)));
4006 XPutPixel (mask_img
, x
, y
,
4007 (!EQ (color_val
, Qt
) ? PIX_MASK_DRAW
4008 : (have_mask
= 1, PIX_MASK_RETAIN
)));
4010 if (EQ (color_val
, Qt
))
4011 ns_set_alpha (ximg
, x
, y
, 0);
4019 img
->height
= height
;
4021 /* Maybe fill in the background field while we have ximg handy. */
4022 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
4023 IMAGE_BACKGROUND (img
, f
, ximg
);
4025 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
4026 x_destroy_x_image (ximg
);
4030 /* Fill in the background_transparent field while we have the
4032 image_background_transparent (img
, f
, mask_img
);
4034 x_put_x_image (f
, mask_img
, img
->mask
, width
, height
);
4035 x_destroy_x_image (mask_img
);
4039 x_destroy_x_image (mask_img
);
4040 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4041 img
->mask
= NO_PIXMAP
;
4047 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
4049 x_destroy_x_image (ximg
);
4050 x_destroy_x_image (mask_img
);
4051 x_clear_image (f
, img
);
4060 xpm_load (struct frame
*f
,
4064 Lisp_Object file_name
;
4066 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4067 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
4068 if (STRINGP (file_name
))
4071 unsigned char *contents
;
4074 file
= x_find_image_file (file_name
);
4075 if (!STRINGP (file
))
4077 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
4081 contents
= slurp_file (SDATA (file
), &size
);
4082 if (contents
== NULL
)
4084 image_error ("Error loading XPM image `%s'", img
->spec
, Qnil
);
4088 success_p
= xpm_load_image (f
, img
, contents
, contents
+ size
);
4095 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
4096 if (!STRINGP (data
))
4098 image_error ("Invalid image data `%s'", data
, Qnil
);
4101 success_p
= xpm_load_image (f
, img
, SDATA (data
),
4102 SDATA (data
) + SBYTES (data
));
4108 #endif /* HAVE_NS && !HAVE_XPM */
4112 /***********************************************************************
4114 ***********************************************************************/
4116 #ifdef COLOR_TABLE_SUPPORT
4118 /* An entry in the color table mapping an RGB color to a pixel color. */
4123 unsigned long pixel
;
4125 /* Next in color table collision list. */
4126 struct ct_color
*next
;
4129 /* The bucket vector size to use. Must be prime. */
4133 /* Value is a hash of the RGB color given by R, G, and B. */
4135 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
4137 /* The color hash table. */
4139 static struct ct_color
**ct_table
;
4141 /* Number of entries in the color table. */
4143 static int ct_colors_allocated
;
4146 ct_colors_allocated_max
=
4148 min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof (unsigned long))
4151 /* Initialize the color table. */
4154 init_color_table (void)
4156 int size
= CT_SIZE
* sizeof (*ct_table
);
4157 ct_table
= (struct ct_color
**) xmalloc (size
);
4158 memset (ct_table
, 0, size
);
4159 ct_colors_allocated
= 0;
4163 /* Free memory associated with the color table. */
4166 free_color_table (void)
4169 struct ct_color
*p
, *next
;
4171 for (i
= 0; i
< CT_SIZE
; ++i
)
4172 for (p
= ct_table
[i
]; p
; p
= next
)
4183 /* Value is a pixel color for RGB color R, G, B on frame F. If an
4184 entry for that color already is in the color table, return the
4185 pixel color of that entry. Otherwise, allocate a new color for R,
4186 G, B, and make an entry in the color table. */
4188 static unsigned long
4189 lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
)
4191 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
4192 int i
= hash
% CT_SIZE
;
4194 Display_Info
*dpyinfo
;
4196 /* Handle TrueColor visuals specially, which improves performance by
4197 two orders of magnitude. Freeing colors on TrueColor visuals is
4198 a nop, and pixel colors specify RGB values directly. See also
4199 the Xlib spec, chapter 3.1. */
4200 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
4201 if (dpyinfo
->red_bits
> 0)
4203 unsigned long pr
, pg
, pb
;
4205 /* Apply gamma-correction like normal color allocation does. */
4209 color
.red
= r
, color
.green
= g
, color
.blue
= b
;
4210 gamma_correct (f
, &color
);
4211 r
= color
.red
, g
= color
.green
, b
= color
.blue
;
4214 /* Scale down RGB values to the visual's bits per RGB, and shift
4215 them to the right position in the pixel color. Note that the
4216 original RGB values are 16-bit values, as usual in X. */
4217 pr
= (r
>> (16 - dpyinfo
->red_bits
)) << dpyinfo
->red_offset
;
4218 pg
= (g
>> (16 - dpyinfo
->green_bits
)) << dpyinfo
->green_offset
;
4219 pb
= (b
>> (16 - dpyinfo
->blue_bits
)) << dpyinfo
->blue_offset
;
4221 /* Assemble the pixel color. */
4222 return pr
| pg
| pb
;
4225 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4226 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
4232 #ifdef HAVE_X_WINDOWS
4240 if (ct_colors_allocated_max
<= ct_colors_allocated
)
4241 return FRAME_FOREGROUND_PIXEL (f
);
4243 #ifdef HAVE_X_WINDOWS
4248 cmap
= FRAME_X_COLORMAP (f
);
4249 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4252 ++ct_colors_allocated
;
4253 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4257 p
->pixel
= color
.pixel
;
4258 p
->next
= ct_table
[i
];
4262 return FRAME_FOREGROUND_PIXEL (f
);
4266 color
= PALETTERGB (r
, g
, b
);
4268 color
= RGB_TO_ULONG (r
, g
, b
);
4269 #endif /* HAVE_NTGUI */
4270 ++ct_colors_allocated
;
4271 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4276 p
->next
= ct_table
[i
];
4278 #endif /* HAVE_X_WINDOWS */
4286 /* Look up pixel color PIXEL which is used on frame F in the color
4287 table. If not already present, allocate it. Value is PIXEL. */
4289 static unsigned long
4290 lookup_pixel_color (struct frame
*f
, unsigned long pixel
)
4292 int i
= pixel
% CT_SIZE
;
4295 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4296 if (p
->pixel
== pixel
)
4305 if (ct_colors_allocated_max
<= ct_colors_allocated
)
4306 return FRAME_FOREGROUND_PIXEL (f
);
4308 #ifdef HAVE_X_WINDOWS
4309 cmap
= FRAME_X_COLORMAP (f
);
4310 color
.pixel
= pixel
;
4311 x_query_color (f
, &color
);
4312 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4315 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
4316 color
.pixel
= pixel
;
4317 XQueryColor (NULL
, cmap
, &color
);
4318 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4320 #endif /* HAVE_X_WINDOWS */
4324 ++ct_colors_allocated
;
4326 p
= (struct ct_color
*) xmalloc (sizeof *p
);
4331 p
->next
= ct_table
[i
];
4335 return FRAME_FOREGROUND_PIXEL (f
);
4341 /* Value is a vector of all pixel colors contained in the color table,
4342 allocated via xmalloc. Set *N to the number of colors. */
4344 static unsigned long *
4345 colors_in_color_table (int *n
)
4349 unsigned long *colors
;
4351 if (ct_colors_allocated
== 0)
4358 colors
= (unsigned long *) xmalloc (ct_colors_allocated
4360 *n
= ct_colors_allocated
;
4362 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
4363 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4364 colors
[j
++] = p
->pixel
;
4370 #else /* COLOR_TABLE_SUPPORT */
4372 static unsigned long
4373 lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
)
4375 unsigned long pixel
;
4378 pixel
= PALETTERGB (r
>> 8, g
>> 8, b
>> 8);
4379 #endif /* HAVE_NTGUI */
4382 pixel
= RGB_TO_ULONG (r
>> 8, g
>> 8, b
>> 8);
4383 #endif /* HAVE_NS */
4388 init_color_table (void)
4391 #endif /* COLOR_TABLE_SUPPORT */
4394 /***********************************************************************
4396 ***********************************************************************/
4398 static XColor
*x_to_xcolors (struct frame
*, struct image
*, int);
4399 static void x_from_xcolors (struct frame
*, struct image
*, XColor
*);
4400 static void x_detect_edges (struct frame
*, struct image
*, int[9], int);
4403 static void XPutPixel (XImagePtr
, int, int, COLORREF
);
4404 #endif /* HAVE_NTGUI */
4406 /* Edge detection matrices for different edge-detection
4409 static int emboss_matrix
[9] = {
4411 2, -1, 0, /* y - 1 */
4413 0, 1, -2 /* y + 1 */
4416 static int laplace_matrix
[9] = {
4418 1, 0, 0, /* y - 1 */
4420 0, 0, -1 /* y + 1 */
4423 /* Value is the intensity of the color whose red/green/blue values
4426 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
4429 /* On frame F, return an array of XColor structures describing image
4430 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
4431 non-zero means also fill the red/green/blue members of the XColor
4432 structures. Value is a pointer to the array of XColors structures,
4433 allocated with xmalloc; it must be freed by the caller. */
4436 x_to_xcolors (struct frame
*f
, struct image
*img
, int rgb_p
)
4440 XImagePtr_or_DC ximg
;
4444 #endif /* HAVE_NTGUI */
4446 if (min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *colors
/ img
->width
< img
->height
)
4447 memory_full (SIZE_MAX
);
4448 colors
= (XColor
*) xmalloc (sizeof *colors
* img
->width
* img
->height
);
4451 /* Get the X image IMG->pixmap. */
4452 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
4453 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4455 /* Load the image into a memory device context. */
4456 hdc
= get_frame_dc (f
);
4457 ximg
= CreateCompatibleDC (hdc
);
4458 release_frame_dc (f
, hdc
);
4459 prev
= SelectObject (ximg
, img
->pixmap
);
4460 #endif /* HAVE_NTGUI */
4462 /* Fill the `pixel' members of the XColor array. I wished there
4463 were an easy and portable way to circumvent XGetPixel. */
4465 for (y
= 0; y
< img
->height
; ++y
)
4469 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
4470 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4471 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4473 x_query_colors (f
, row
, img
->width
);
4477 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4479 /* W32_TODO: palette support needed here? */
4480 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4483 p
->red
= RED16_FROM_ULONG (p
->pixel
);
4484 p
->green
= GREEN16_FROM_ULONG (p
->pixel
);
4485 p
->blue
= BLUE16_FROM_ULONG (p
->pixel
);
4488 #endif /* HAVE_X_WINDOWS */
4491 Destroy_Image (ximg
, prev
);
4498 /* Put a pixel of COLOR at position X, Y in XIMG. XIMG must have been
4499 created with CreateDIBSection, with the pointer to the bit values
4500 stored in ximg->data. */
4503 XPutPixel (XImagePtr ximg
, int x
, int y
, COLORREF color
)
4505 int width
= ximg
->info
.bmiHeader
.biWidth
;
4506 unsigned char * pixel
;
4508 /* True color images. */
4509 if (ximg
->info
.bmiHeader
.biBitCount
== 24)
4511 int rowbytes
= width
* 3;
4512 /* Ensure scanlines are aligned on 4 byte boundaries. */
4514 rowbytes
+= 4 - (rowbytes
% 4);
4516 pixel
= ximg
->data
+ y
* rowbytes
+ x
* 3;
4517 /* Windows bitmaps are in BGR order. */
4518 *pixel
= GetBValue (color
);
4519 *(pixel
+ 1) = GetGValue (color
);
4520 *(pixel
+ 2) = GetRValue (color
);
4522 /* Monochrome images. */
4523 else if (ximg
->info
.bmiHeader
.biBitCount
== 1)
4525 int rowbytes
= width
/ 8;
4526 /* Ensure scanlines are aligned on 4 byte boundaries. */
4528 rowbytes
+= 4 - (rowbytes
% 4);
4529 pixel
= ximg
->data
+ y
* rowbytes
+ x
/ 8;
4530 /* Filter out palette info. */
4531 if (color
& 0x00ffffff)
4532 *pixel
= *pixel
| (1 << x
% 8);
4534 *pixel
= *pixel
& ~(1 << x
% 8);
4537 image_error ("XPutPixel: palette image not supported", Qnil
, Qnil
);
4540 #endif /* HAVE_NTGUI */
4542 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
4543 RGB members are set. F is the frame on which this all happens.
4544 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
4547 x_from_xcolors (struct frame
*f
, struct image
*img
, XColor
*colors
)
4550 XImagePtr oimg
= NULL
;
4554 init_color_table ();
4556 x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
4559 for (y
= 0; y
< img
->height
; ++y
)
4560 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4562 unsigned long pixel
;
4563 pixel
= lookup_rgb_color (f
, p
->red
, p
->green
, p
->blue
);
4564 XPutPixel (oimg
, x
, y
, pixel
);
4568 x_clear_image_1 (f
, img
, 1, 0, 1);
4570 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
4571 x_destroy_x_image (oimg
);
4572 img
->pixmap
= pixmap
;
4573 #ifdef COLOR_TABLE_SUPPORT
4574 img
->colors
= colors_in_color_table (&img
->ncolors
);
4575 free_color_table ();
4576 #endif /* COLOR_TABLE_SUPPORT */
4580 /* On frame F, perform edge-detection on image IMG.
4582 MATRIX is a nine-element array specifying the transformation
4583 matrix. See emboss_matrix for an example.
4585 COLOR_ADJUST is a color adjustment added to each pixel of the
4589 x_detect_edges (struct frame
*f
, struct image
*img
, int *matrix
, int color_adjust
)
4591 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4595 for (i
= sum
= 0; i
< 9; ++i
)
4596 sum
+= eabs (matrix
[i
]);
4598 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
4600 if (min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *new / img
->width
< img
->height
)
4601 memory_full (SIZE_MAX
);
4602 new = (XColor
*) xmalloc (sizeof *new * img
->width
* img
->height
);
4604 for (y
= 0; y
< img
->height
; ++y
)
4606 p
= COLOR (new, 0, y
);
4607 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4608 p
= COLOR (new, img
->width
- 1, y
);
4609 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4612 for (x
= 1; x
< img
->width
- 1; ++x
)
4614 p
= COLOR (new, x
, 0);
4615 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4616 p
= COLOR (new, x
, img
->height
- 1);
4617 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4620 for (y
= 1; y
< img
->height
- 1; ++y
)
4622 p
= COLOR (new, 1, y
);
4624 for (x
= 1; x
< img
->width
- 1; ++x
, ++p
)
4626 int r
, g
, b
, yy
, xx
;
4629 for (yy
= y
- 1; yy
< y
+ 2; ++yy
)
4630 for (xx
= x
- 1; xx
< x
+ 2; ++xx
, ++i
)
4633 XColor
*t
= COLOR (colors
, xx
, yy
);
4634 r
+= matrix
[i
] * t
->red
;
4635 g
+= matrix
[i
] * t
->green
;
4636 b
+= matrix
[i
] * t
->blue
;
4639 r
= (r
/ sum
+ color_adjust
) & 0xffff;
4640 g
= (g
/ sum
+ color_adjust
) & 0xffff;
4641 b
= (b
/ sum
+ color_adjust
) & 0xffff;
4642 p
->red
= p
->green
= p
->blue
= COLOR_INTENSITY (r
, g
, b
);
4647 x_from_xcolors (f
, img
, new);
4653 /* Perform the pre-defined `emboss' edge-detection on image IMG
4657 x_emboss (struct frame
*f
, struct image
*img
)
4659 x_detect_edges (f
, img
, emboss_matrix
, 0xffff / 2);
4663 /* Transform image IMG which is used on frame F with a Laplace
4664 edge-detection algorithm. The result is an image that can be used
4665 to draw disabled buttons, for example. */
4668 x_laplace (struct frame
*f
, struct image
*img
)
4670 x_detect_edges (f
, img
, laplace_matrix
, 45000);
4674 /* Perform edge-detection on image IMG on frame F, with specified
4675 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
4677 MATRIX must be either
4679 - a list of at least 9 numbers in row-major form
4680 - a vector of at least 9 numbers
4682 COLOR_ADJUST nil means use a default; otherwise it must be a
4686 x_edge_detection (struct frame
*f
, struct image
*img
, Lisp_Object matrix
,
4687 Lisp_Object color_adjust
)
4695 i
< 9 && CONSP (matrix
) && NUMBERP (XCAR (matrix
));
4696 ++i
, matrix
= XCDR (matrix
))
4697 trans
[i
] = XFLOATINT (XCAR (matrix
));
4699 else if (VECTORP (matrix
) && ASIZE (matrix
) >= 9)
4701 for (i
= 0; i
< 9 && NUMBERP (AREF (matrix
, i
)); ++i
)
4702 trans
[i
] = XFLOATINT (AREF (matrix
, i
));
4705 if (NILP (color_adjust
))
4706 color_adjust
= make_number (0xffff / 2);
4708 if (i
== 9 && NUMBERP (color_adjust
))
4709 x_detect_edges (f
, img
, trans
, XFLOATINT (color_adjust
));
4713 /* Transform image IMG on frame F so that it looks disabled. */
4716 x_disable_image (struct frame
*f
, struct image
*img
)
4718 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
4720 int n_planes
= dpyinfo
->n_planes
* dpyinfo
->n_cbits
;
4722 int n_planes
= dpyinfo
->n_planes
;
4723 #endif /* HAVE_NTGUI */
4727 /* Color (or grayscale). Convert to gray, and equalize. Just
4728 drawing such images with a stipple can look very odd, so
4729 we're using this method instead. */
4730 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4732 const int h
= 15000;
4733 const int l
= 30000;
4735 for (p
= colors
, end
= colors
+ img
->width
* img
->height
;
4739 int i
= COLOR_INTENSITY (p
->red
, p
->green
, p
->blue
);
4740 int i2
= (0xffff - h
- l
) * i
/ 0xffff + l
;
4741 p
->red
= p
->green
= p
->blue
= i2
;
4744 x_from_xcolors (f
, img
, colors
);
4747 /* Draw a cross over the disabled image, if we must or if we
4749 if (n_planes
< 2 || cross_disabled_images
)
4752 Display
*dpy
= FRAME_X_DISPLAY (f
);
4755 #ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
4757 #define MaskForeground(f) WHITE_PIX_DEFAULT (f)
4759 gc
= XCreateGC (dpy
, img
->pixmap
, 0, NULL
);
4760 XSetForeground (dpy
, gc
, BLACK_PIX_DEFAULT (f
));
4761 XDrawLine (dpy
, img
->pixmap
, gc
, 0, 0,
4762 img
->width
- 1, img
->height
- 1);
4763 XDrawLine (dpy
, img
->pixmap
, gc
, 0, img
->height
- 1,
4769 gc
= XCreateGC (dpy
, img
->mask
, 0, NULL
);
4770 XSetForeground (dpy
, gc
, MaskForeground (f
));
4771 XDrawLine (dpy
, img
->mask
, gc
, 0, 0,
4772 img
->width
- 1, img
->height
- 1);
4773 XDrawLine (dpy
, img
->mask
, gc
, 0, img
->height
- 1,
4777 #endif /* !HAVE_NS */
4782 hdc
= get_frame_dc (f
);
4783 bmpdc
= CreateCompatibleDC (hdc
);
4784 release_frame_dc (f
, hdc
);
4786 prev
= SelectObject (bmpdc
, img
->pixmap
);
4788 SetTextColor (bmpdc
, BLACK_PIX_DEFAULT (f
));
4789 MoveToEx (bmpdc
, 0, 0, NULL
);
4790 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
4791 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
4792 LineTo (bmpdc
, img
->width
- 1, 0);
4796 SelectObject (bmpdc
, img
->mask
);
4797 SetTextColor (bmpdc
, WHITE_PIX_DEFAULT (f
));
4798 MoveToEx (bmpdc
, 0, 0, NULL
);
4799 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
4800 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
4801 LineTo (bmpdc
, img
->width
- 1, 0);
4803 SelectObject (bmpdc
, prev
);
4805 #endif /* HAVE_NTGUI */
4810 /* Build a mask for image IMG which is used on frame F. FILE is the
4811 name of an image file, for error messages. HOW determines how to
4812 determine the background color of IMG. If it is a list '(R G B)',
4813 with R, G, and B being integers >= 0, take that as the color of the
4814 background. Otherwise, determine the background color of IMG
4815 heuristically. Value is non-zero if successful. */
4818 x_build_heuristic_mask (struct frame
*f
, struct image
*img
, Lisp_Object how
)
4820 XImagePtr_or_DC ximg
;
4828 #endif /* HAVE_NTGUI */
4829 int x
, y
, rc
, use_img_background
;
4830 unsigned long bg
= 0;
4834 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4835 img
->mask
= NO_PIXMAP
;
4836 img
->background_transparent_valid
= 0;
4841 /* Create an image and pixmap serving as mask. */
4842 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
4843 &mask_img
, &img
->mask
);
4846 #endif /* !HAVE_NS */
4848 /* Get the X image of IMG->pixmap. */
4849 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
, 0, 0,
4850 img
->width
, img
->height
,
4853 /* Create the bit array serving as mask. */
4854 row_width
= (img
->width
+ 7) / 8;
4855 mask_img
= xmalloc (row_width
* img
->height
);
4856 memset (mask_img
, 0, row_width
* img
->height
);
4858 /* Create a memory device context for IMG->pixmap. */
4859 frame_dc
= get_frame_dc (f
);
4860 ximg
= CreateCompatibleDC (frame_dc
);
4861 release_frame_dc (f
, frame_dc
);
4862 prev
= SelectObject (ximg
, img
->pixmap
);
4863 #endif /* HAVE_NTGUI */
4865 /* Determine the background color of ximg. If HOW is `(R G B)'
4866 take that as color. Otherwise, use the image's background color. */
4867 use_img_background
= 1;
4873 for (i
= 0; i
< 3 && CONSP (how
) && NATNUMP (XCAR (how
)); ++i
)
4875 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
4879 if (i
== 3 && NILP (how
))
4881 char color_name
[30];
4882 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
4885 0x00ffffff & /* Filter out palette info. */
4886 #endif /* HAVE_NTGUI */
4887 x_alloc_image_color (f
, img
, build_string (color_name
), 0));
4888 use_img_background
= 0;
4892 if (use_img_background
)
4893 bg
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
4895 /* Set all bits in mask_img to 1 whose color in ximg is different
4896 from the background color bg. */
4898 for (y
= 0; y
< img
->height
; ++y
)
4899 for (x
= 0; x
< img
->width
; ++x
)
4901 XPutPixel (mask_img
, x
, y
, (XGetPixel (ximg
, x
, y
) != bg
4902 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
));
4904 if (XGetPixel (ximg
, x
, y
) == bg
)
4905 ns_set_alpha (ximg
, x
, y
, 0);
4906 #endif /* HAVE_NS */
4908 /* Fill in the background_transparent field while we have the mask handy. */
4909 image_background_transparent (img
, f
, mask_img
);
4911 /* Put mask_img into img->mask. */
4912 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
4913 x_destroy_x_image (mask_img
);
4914 #endif /* !HAVE_NS */
4916 for (y
= 0; y
< img
->height
; ++y
)
4917 for (x
= 0; x
< img
->width
; ++x
)
4919 COLORREF p
= GetPixel (ximg
, x
, y
);
4921 mask_img
[y
* row_width
+ x
/ 8] |= 1 << (x
% 8);
4924 /* Create the mask image. */
4925 img
->mask
= w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
,
4927 /* Fill in the background_transparent field while we have the mask handy. */
4928 SelectObject (ximg
, img
->mask
);
4929 image_background_transparent (img
, f
, ximg
);
4931 /* Was: x_destroy_x_image ((XImagePtr )mask_img); which seems bogus ++kfs */
4933 #endif /* HAVE_NTGUI */
4935 Destroy_Image (ximg
, prev
);
4941 /***********************************************************************
4942 PBM (mono, gray, color)
4943 ***********************************************************************/
4945 static int pbm_image_p (Lisp_Object object
);
4946 static int pbm_load (struct frame
*f
, struct image
*img
);
4947 static int pbm_scan_number (unsigned char **, unsigned char *);
4949 /* The symbol `pbm' identifying images of this type. */
4951 static Lisp_Object Qpbm
;
4953 /* Indices of image specification fields in gs_format, below. */
4955 enum pbm_keyword_index
4971 /* Vector of image_keyword structures describing the format
4972 of valid user-defined image specifications. */
4974 static const struct image_keyword pbm_format
[PBM_LAST
] =
4976 {":type", IMAGE_SYMBOL_VALUE
, 1},
4977 {":file", IMAGE_STRING_VALUE
, 0},
4978 {":data", IMAGE_STRING_VALUE
, 0},
4979 {":ascent", IMAGE_ASCENT_VALUE
, 0},
4980 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
4981 {":relief", IMAGE_INTEGER_VALUE
, 0},
4982 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4983 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4984 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4985 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
4986 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
4989 /* Structure describing the image type `pbm'. */
4991 static struct image_type pbm_type
=
5001 /* Return non-zero if OBJECT is a valid PBM image specification. */
5004 pbm_image_p (Lisp_Object object
)
5006 struct image_keyword fmt
[PBM_LAST
];
5008 memcpy (fmt
, pbm_format
, sizeof fmt
);
5010 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
))
5013 /* Must specify either :data or :file. */
5014 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
5018 /* Scan a decimal number from *S and return it. Advance *S while
5019 reading the number. END is the end of the string. Value is -1 at
5023 pbm_scan_number (unsigned char **s
, unsigned char *end
)
5025 int c
= 0, val
= -1;
5029 /* Skip white-space. */
5030 while (*s
< end
&& (c
= *(*s
)++, isspace (c
)))
5035 /* Skip comment to end of line. */
5036 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
5039 else if (isdigit (c
))
5041 /* Read decimal number. */
5043 while (*s
< end
&& (c
= *(*s
)++, isdigit (c
)))
5044 val
= 10 * val
+ c
- '0';
5056 #if 0 /* Unused. ++kfs */
5058 /* Read FILE into memory. Value is a pointer to a buffer allocated
5059 with xmalloc holding FILE's contents. Value is null if an error
5060 occurred. *SIZE is set to the size of the file. */
5063 pbm_read_file (Lisp_Object file
, int *size
)
5069 if (stat (SDATA (file
), &st
) == 0
5070 && (fp
= fopen (SDATA (file
), "rb")) != NULL
5071 && 0 <= st
.st_size
&& st
.st_size
<= min (PTRDIFF_MAX
, SIZE_MAX
)
5072 && (buf
= (char *) xmalloc (st
.st_size
),
5073 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
5092 #endif /* HAVE_NTGUI */
5094 /* Load PBM image IMG for use on frame F. */
5097 pbm_load (struct frame
*f
, struct image
*img
)
5100 int width
, height
, max_color_idx
= 0;
5102 Lisp_Object file
, specified_file
;
5103 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
5104 unsigned char *contents
= NULL
;
5105 unsigned char *end
, *p
;
5108 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5110 if (STRINGP (specified_file
))
5112 file
= x_find_image_file (specified_file
);
5113 if (!STRINGP (file
))
5115 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5119 contents
= slurp_file (SSDATA (file
), &size
);
5120 if (contents
== NULL
)
5122 image_error ("Error reading `%s'", file
, Qnil
);
5127 end
= contents
+ size
;
5132 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5133 if (!STRINGP (data
))
5135 image_error ("Invalid image data `%s'", data
, Qnil
);
5139 end
= p
+ SBYTES (data
);
5142 /* Check magic number. */
5143 if (end
- p
< 2 || *p
++ != 'P')
5145 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5154 raw_p
= 0, type
= PBM_MONO
;
5158 raw_p
= 0, type
= PBM_GRAY
;
5162 raw_p
= 0, type
= PBM_COLOR
;
5166 raw_p
= 1, type
= PBM_MONO
;
5170 raw_p
= 1, type
= PBM_GRAY
;
5174 raw_p
= 1, type
= PBM_COLOR
;
5178 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5182 /* Read width, height, maximum color-component. Characters
5183 starting with `#' up to the end of a line are ignored. */
5184 width
= pbm_scan_number (&p
, end
);
5185 height
= pbm_scan_number (&p
, end
);
5187 if (type
!= PBM_MONO
)
5189 max_color_idx
= pbm_scan_number (&p
, end
);
5190 if (max_color_idx
> 65535 || max_color_idx
< 0)
5192 image_error ("Unsupported maximum PBM color value", Qnil
, Qnil
);
5197 if (!check_image_size (f
, width
, height
))
5199 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
5203 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
5204 &ximg
, &img
->pixmap
))
5207 /* Initialize the color hash table. */
5208 init_color_table ();
5210 if (type
== PBM_MONO
)
5213 struct image_keyword fmt
[PBM_LAST
];
5214 unsigned long fg
= FRAME_FOREGROUND_PIXEL (f
);
5215 unsigned long bg
= FRAME_BACKGROUND_PIXEL (f
);
5217 /* Parse the image specification. */
5218 memcpy (fmt
, pbm_format
, sizeof fmt
);
5219 parse_image_spec (img
->spec
, fmt
, PBM_LAST
, Qpbm
);
5221 /* Get foreground and background colors, maybe allocate colors. */
5222 if (fmt
[PBM_FOREGROUND
].count
5223 && STRINGP (fmt
[PBM_FOREGROUND
].value
))
5224 fg
= x_alloc_image_color (f
, img
, fmt
[PBM_FOREGROUND
].value
, fg
);
5225 if (fmt
[PBM_BACKGROUND
].count
5226 && STRINGP (fmt
[PBM_BACKGROUND
].value
))
5228 bg
= x_alloc_image_color (f
, img
, fmt
[PBM_BACKGROUND
].value
, bg
);
5229 img
->background
= bg
;
5230 img
->background_valid
= 1;
5233 for (y
= 0; y
< height
; ++y
)
5234 for (x
= 0; x
< width
; ++x
)
5242 x_destroy_x_image (ximg
);
5243 x_clear_image (f
, img
);
5244 image_error ("Invalid image size in image `%s'",
5254 g
= pbm_scan_number (&p
, end
);
5256 XPutPixel (ximg
, x
, y
, g
? fg
: bg
);
5261 int expected_size
= height
* width
;
5262 if (max_color_idx
> 255)
5264 if (type
== PBM_COLOR
)
5267 if (raw_p
&& p
+ expected_size
> end
)
5269 x_destroy_x_image (ximg
);
5270 x_clear_image (f
, img
);
5271 image_error ("Invalid image size in image `%s'",
5276 for (y
= 0; y
< height
; ++y
)
5277 for (x
= 0; x
< width
; ++x
)
5281 if (type
== PBM_GRAY
&& raw_p
)
5284 if (max_color_idx
> 255)
5285 r
= g
= b
= r
* 256 + *p
++;
5287 else if (type
== PBM_GRAY
)
5288 r
= g
= b
= pbm_scan_number (&p
, end
);
5292 if (max_color_idx
> 255)
5295 if (max_color_idx
> 255)
5298 if (max_color_idx
> 255)
5303 r
= pbm_scan_number (&p
, end
);
5304 g
= pbm_scan_number (&p
, end
);
5305 b
= pbm_scan_number (&p
, end
);
5308 if (r
< 0 || g
< 0 || b
< 0)
5310 x_destroy_x_image (ximg
);
5311 image_error ("Invalid pixel value in image `%s'",
5316 /* RGB values are now in the range 0..max_color_idx.
5317 Scale this to the range 0..0xffff supported by X. */
5318 r
= (double) r
* 65535 / max_color_idx
;
5319 g
= (double) g
* 65535 / max_color_idx
;
5320 b
= (double) b
* 65535 / max_color_idx
;
5321 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
5325 #ifdef COLOR_TABLE_SUPPORT
5326 /* Store in IMG->colors the colors allocated for the image, and
5327 free the color table. */
5328 img
->colors
= colors_in_color_table (&img
->ncolors
);
5329 free_color_table ();
5330 #endif /* COLOR_TABLE_SUPPORT */
5333 img
->height
= height
;
5335 /* Maybe fill in the background field while we have ximg handy. */
5337 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
5338 /* Casting avoids a GCC warning. */
5339 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
5341 /* Put the image into a pixmap. */
5342 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
5343 x_destroy_x_image (ximg
);
5345 /* X and W32 versions did it here, MAC version above. ++kfs
5347 img->height = height; */
5354 /***********************************************************************
5356 ***********************************************************************/
5358 #if defined (HAVE_PNG) || defined (HAVE_NS)
5360 /* Function prototypes. */
5362 static int png_image_p (Lisp_Object object
);
5363 static int png_load (struct frame
*f
, struct image
*img
);
5365 /* The symbol `png' identifying images of this type. */
5367 static Lisp_Object Qpng
;
5369 /* Indices of image specification fields in png_format, below. */
5371 enum png_keyword_index
5386 /* Vector of image_keyword structures describing the format
5387 of valid user-defined image specifications. */
5389 static const struct image_keyword png_format
[PNG_LAST
] =
5391 {":type", IMAGE_SYMBOL_VALUE
, 1},
5392 {":data", IMAGE_STRING_VALUE
, 0},
5393 {":file", IMAGE_STRING_VALUE
, 0},
5394 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5395 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
5396 {":relief", IMAGE_INTEGER_VALUE
, 0},
5397 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5398 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5399 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5400 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
5403 /* Structure describing the image type `png'. */
5405 static struct image_type png_type
=
5414 /* Return non-zero if OBJECT is a valid PNG image specification. */
5417 png_image_p (Lisp_Object object
)
5419 struct image_keyword fmt
[PNG_LAST
];
5420 memcpy (fmt
, png_format
, sizeof fmt
);
5422 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
5425 /* Must specify either the :data or :file keyword. */
5426 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
5429 #endif /* HAVE_PNG || HAVE_NS */
5435 /* PNG library details. */
5437 DEF_IMGLIB_FN (png_voidp
, png_get_io_ptr
, (png_structp
));
5438 DEF_IMGLIB_FN (int, png_sig_cmp
, (png_bytep
, png_size_t
, png_size_t
));
5439 DEF_IMGLIB_FN (png_structp
, png_create_read_struct
, (png_const_charp
, png_voidp
,
5440 png_error_ptr
, png_error_ptr
));
5441 DEF_IMGLIB_FN (png_infop
, png_create_info_struct
, (png_structp
));
5442 DEF_IMGLIB_FN (void, png_destroy_read_struct
, (png_structpp
, png_infopp
, png_infopp
));
5443 DEF_IMGLIB_FN (void, png_set_read_fn
, (png_structp
, png_voidp
, png_rw_ptr
));
5444 DEF_IMGLIB_FN (void, png_set_sig_bytes
, (png_structp
, int));
5445 DEF_IMGLIB_FN (void, png_read_info
, (png_structp
, png_infop
));
5446 DEF_IMGLIB_FN (png_uint_32
, png_get_IHDR
, (png_structp
, png_infop
,
5447 png_uint_32
*, png_uint_32
*,
5448 int *, int *, int *, int *, int *));
5449 DEF_IMGLIB_FN (png_uint_32
, png_get_valid
, (png_structp
, png_infop
, png_uint_32
));
5450 DEF_IMGLIB_FN (void, png_set_strip_16
, (png_structp
));
5451 DEF_IMGLIB_FN (void, png_set_expand
, (png_structp
));
5452 DEF_IMGLIB_FN (void, png_set_gray_to_rgb
, (png_structp
));
5453 DEF_IMGLIB_FN (void, png_set_background
, (png_structp
, png_color_16p
,
5455 DEF_IMGLIB_FN (png_uint_32
, png_get_bKGD
, (png_structp
, png_infop
, png_color_16p
*));
5456 DEF_IMGLIB_FN (void, png_read_update_info
, (png_structp
, png_infop
));
5457 DEF_IMGLIB_FN (png_byte
, png_get_channels
, (png_structp
, png_infop
));
5458 DEF_IMGLIB_FN (png_size_t
, png_get_rowbytes
, (png_structp
, png_infop
));
5459 DEF_IMGLIB_FN (void, png_read_image
, (png_structp
, png_bytepp
));
5460 DEF_IMGLIB_FN (void, png_read_end
, (png_structp
, png_infop
));
5461 DEF_IMGLIB_FN (void, png_error
, (png_structp
, png_const_charp
));
5463 #if (PNG_LIBPNG_VER >= 10500)
5464 DEF_IMGLIB_FN (void, png_longjmp
, (png_structp
, int));
5465 DEF_IMGLIB_FN (jmp_buf *, png_set_longjmp_fn
, (png_structp
, png_longjmp_ptr
, size_t));
5466 #endif /* libpng version >= 1.5 */
5469 init_png_functions (Lisp_Object libraries
)
5473 if (!(library
= w32_delayed_load (libraries
, Qpng
)))
5476 LOAD_IMGLIB_FN (library
, png_get_io_ptr
);
5477 LOAD_IMGLIB_FN (library
, png_sig_cmp
);
5478 LOAD_IMGLIB_FN (library
, png_create_read_struct
);
5479 LOAD_IMGLIB_FN (library
, png_create_info_struct
);
5480 LOAD_IMGLIB_FN (library
, png_destroy_read_struct
);
5481 LOAD_IMGLIB_FN (library
, png_set_read_fn
);
5482 LOAD_IMGLIB_FN (library
, png_set_sig_bytes
);
5483 LOAD_IMGLIB_FN (library
, png_read_info
);
5484 LOAD_IMGLIB_FN (library
, png_get_IHDR
);
5485 LOAD_IMGLIB_FN (library
, png_get_valid
);
5486 LOAD_IMGLIB_FN (library
, png_set_strip_16
);
5487 LOAD_IMGLIB_FN (library
, png_set_expand
);
5488 LOAD_IMGLIB_FN (library
, png_set_gray_to_rgb
);
5489 LOAD_IMGLIB_FN (library
, png_set_background
);
5490 LOAD_IMGLIB_FN (library
, png_get_bKGD
);
5491 LOAD_IMGLIB_FN (library
, png_read_update_info
);
5492 LOAD_IMGLIB_FN (library
, png_get_channels
);
5493 LOAD_IMGLIB_FN (library
, png_get_rowbytes
);
5494 LOAD_IMGLIB_FN (library
, png_read_image
);
5495 LOAD_IMGLIB_FN (library
, png_read_end
);
5496 LOAD_IMGLIB_FN (library
, png_error
);
5498 #if (PNG_LIBPNG_VER >= 10500)
5499 LOAD_IMGLIB_FN (library
, png_longjmp
);
5500 LOAD_IMGLIB_FN (library
, png_set_longjmp_fn
);
5501 #endif /* libpng version >= 1.5 */
5507 #define fn_png_get_io_ptr png_get_io_ptr
5508 #define fn_png_sig_cmp png_sig_cmp
5509 #define fn_png_create_read_struct png_create_read_struct
5510 #define fn_png_create_info_struct png_create_info_struct
5511 #define fn_png_destroy_read_struct png_destroy_read_struct
5512 #define fn_png_set_read_fn png_set_read_fn
5513 #define fn_png_set_sig_bytes png_set_sig_bytes
5514 #define fn_png_read_info png_read_info
5515 #define fn_png_get_IHDR png_get_IHDR
5516 #define fn_png_get_valid png_get_valid
5517 #define fn_png_set_strip_16 png_set_strip_16
5518 #define fn_png_set_expand png_set_expand
5519 #define fn_png_set_gray_to_rgb png_set_gray_to_rgb
5520 #define fn_png_set_background png_set_background
5521 #define fn_png_get_bKGD png_get_bKGD
5522 #define fn_png_read_update_info png_read_update_info
5523 #define fn_png_get_channels png_get_channels
5524 #define fn_png_get_rowbytes png_get_rowbytes
5525 #define fn_png_read_image png_read_image
5526 #define fn_png_read_end png_read_end
5527 #define fn_png_error png_error
5529 #if (PNG_LIBPNG_VER >= 10500)
5530 #define fn_png_longjmp png_longjmp
5531 #define fn_png_set_longjmp_fn png_set_longjmp_fn
5532 #endif /* libpng version >= 1.5 */
5534 #endif /* HAVE_NTGUI */
5537 #if (PNG_LIBPNG_VER < 10500)
5538 #define PNG_LONGJMP(ptr) (longjmp ((ptr)->jmpbuf, 1))
5539 #define PNG_JMPBUF(ptr) ((ptr)->jmpbuf)
5541 /* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908) */
5542 #define PNG_LONGJMP(ptr) (fn_png_longjmp ((ptr), 1))
5543 #define PNG_JMPBUF(ptr) \
5544 (*fn_png_set_longjmp_fn ((ptr), longjmp, sizeof (jmp_buf)))
5547 /* Error and warning handlers installed when the PNG library
5550 static _Noreturn
void
5551 my_png_error (png_struct
*png_ptr
, const char *msg
)
5553 eassert (png_ptr
!= NULL
);
5554 /* Avoid compiler warning about deprecated direct access to
5555 png_ptr's fields in libpng versions 1.4.x. */
5556 image_error ("PNG error: %s", build_string (msg
), Qnil
);
5557 PNG_LONGJMP (png_ptr
);
5562 my_png_warning (png_struct
*png_ptr
, const char *msg
)
5564 eassert (png_ptr
!= NULL
);
5565 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
5568 /* Memory source for PNG decoding. */
5570 struct png_memory_storage
5572 unsigned char *bytes
; /* The data */
5573 ptrdiff_t len
; /* How big is it? */
5574 ptrdiff_t index
; /* Where are we? */
5578 /* Function set as reader function when reading PNG image from memory.
5579 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5580 bytes from the input to DATA. */
5583 png_read_from_memory (png_structp png_ptr
, png_bytep data
, png_size_t length
)
5585 struct png_memory_storage
*tbr
5586 = (struct png_memory_storage
*) fn_png_get_io_ptr (png_ptr
);
5588 if (length
> tbr
->len
- tbr
->index
)
5589 fn_png_error (png_ptr
, "Read error");
5591 memcpy (data
, tbr
->bytes
+ tbr
->index
, length
);
5592 tbr
->index
= tbr
->index
+ length
;
5596 /* Function set as reader function when reading PNG image from a file.
5597 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5598 bytes from the input to DATA. */
5601 png_read_from_file (png_structp png_ptr
, png_bytep data
, png_size_t length
)
5603 FILE *fp
= (FILE *) fn_png_get_io_ptr (png_ptr
);
5605 if (fread (data
, 1, length
, fp
) < length
)
5606 fn_png_error (png_ptr
, "Read error");
5610 /* Load PNG image IMG for use on frame F. Value is non-zero if
5614 png_load (struct frame
*f
, struct image
*img
)
5616 Lisp_Object file
, specified_file
;
5617 Lisp_Object specified_data
;
5620 XImagePtr ximg
, mask_img
= NULL
;
5621 png_struct
*png_ptr
= NULL
;
5622 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
5623 FILE *volatile fp
= NULL
;
5625 png_byte
* volatile pixels
= NULL
;
5626 png_byte
** volatile rows
= NULL
;
5627 png_uint_32 width
, height
;
5628 int bit_depth
, color_type
, interlace_type
;
5630 png_uint_32 row_bytes
;
5632 struct png_memory_storage tbr
; /* Data to be read */
5634 /* Find out what file to load. */
5635 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5636 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5638 if (NILP (specified_data
))
5640 file
= x_find_image_file (specified_file
);
5641 if (!STRINGP (file
))
5643 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5647 /* Open the image file. */
5648 fp
= fopen (SSDATA (file
), "rb");
5651 image_error ("Cannot open image file `%s'", file
, Qnil
);
5655 /* Check PNG signature. */
5656 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
5657 || fn_png_sig_cmp (sig
, 0, sizeof sig
))
5659 image_error ("Not a PNG file: `%s'", file
, Qnil
);
5666 if (!STRINGP (specified_data
))
5668 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
5672 /* Read from memory. */
5673 tbr
.bytes
= SDATA (specified_data
);
5674 tbr
.len
= SBYTES (specified_data
);
5677 /* Check PNG signature. */
5678 if (tbr
.len
< sizeof sig
5679 || fn_png_sig_cmp (tbr
.bytes
, 0, sizeof sig
))
5681 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
5685 /* Need to skip past the signature. */
5686 tbr
.bytes
+= sizeof (sig
);
5689 /* Initialize read and info structs for PNG lib. */
5690 png_ptr
= fn_png_create_read_struct (PNG_LIBPNG_VER_STRING
,
5695 if (fp
) fclose (fp
);
5699 info_ptr
= fn_png_create_info_struct (png_ptr
);
5702 fn_png_destroy_read_struct (&png_ptr
, NULL
, NULL
);
5703 if (fp
) fclose (fp
);
5707 end_info
= fn_png_create_info_struct (png_ptr
);
5710 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, NULL
);
5711 if (fp
) fclose (fp
);
5715 /* Set error jump-back. We come back here when the PNG library
5716 detects an error. */
5717 if (setjmp (PNG_JMPBUF (png_ptr
)))
5721 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
5724 if (fp
) fclose (fp
);
5728 /* Read image info. */
5729 if (!NILP (specified_data
))
5730 fn_png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
5732 fn_png_set_read_fn (png_ptr
, (void *) fp
, png_read_from_file
);
5734 fn_png_set_sig_bytes (png_ptr
, sizeof sig
);
5735 fn_png_read_info (png_ptr
, info_ptr
);
5736 fn_png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
5737 &interlace_type
, NULL
, NULL
);
5739 if (! (width
<= INT_MAX
&& height
<= INT_MAX
5740 && check_image_size (f
, width
, height
)))
5742 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
5746 /* Create the X image and pixmap now, so that the work below can be
5747 omitted if the image is too large for X. */
5748 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
5752 /* If image contains simply transparency data, we prefer to
5753 construct a clipping mask. */
5754 if (fn_png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
5759 /* This function is easier to write if we only have to handle
5760 one data format: RGB or RGBA with 8 bits per channel. Let's
5761 transform other formats into that format. */
5763 /* Strip more than 8 bits per channel. */
5764 if (bit_depth
== 16)
5765 fn_png_set_strip_16 (png_ptr
);
5767 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
5769 fn_png_set_expand (png_ptr
);
5771 /* Convert grayscale images to RGB. */
5772 if (color_type
== PNG_COLOR_TYPE_GRAY
5773 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
5774 fn_png_set_gray_to_rgb (png_ptr
);
5776 /* Handle alpha channel by combining the image with a background
5777 color. Do this only if a real alpha channel is supplied. For
5778 simple transparency, we prefer a clipping mask. */
5781 /* png_color_16 *image_bg; */
5782 Lisp_Object specified_bg
5783 = image_spec_value (img
->spec
, QCbackground
, NULL
);
5784 int shift
= (bit_depth
== 16) ? 0 : 8;
5786 if (STRINGP (specified_bg
))
5787 /* The user specified `:background', use that. */
5790 if (x_defined_color (f
, SSDATA (specified_bg
), &color
, 0))
5792 png_color_16 user_bg
;
5794 memset (&user_bg
, 0, sizeof user_bg
);
5795 user_bg
.red
= color
.red
>> shift
;
5796 user_bg
.green
= color
.green
>> shift
;
5797 user_bg
.blue
= color
.blue
>> shift
;
5799 fn_png_set_background (png_ptr
, &user_bg
,
5800 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
5805 /* We use the current frame background, ignoring any default
5806 background color set by the image. */
5807 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
5809 png_color_16 frame_background
;
5811 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
5812 x_query_color (f
, &color
);
5814 memset (&frame_background
, 0, sizeof frame_background
);
5815 frame_background
.red
= color
.red
>> shift
;
5816 frame_background
.green
= color
.green
>> shift
;
5817 frame_background
.blue
= color
.blue
>> shift
;
5818 #endif /* HAVE_X_WINDOWS */
5820 fn_png_set_background (png_ptr
, &frame_background
,
5821 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
5825 /* Update info structure. */
5826 fn_png_read_update_info (png_ptr
, info_ptr
);
5828 /* Get number of channels. Valid values are 1 for grayscale images
5829 and images with a palette, 2 for grayscale images with transparency
5830 information (alpha channel), 3 for RGB images, and 4 for RGB
5831 images with alpha channel, i.e. RGBA. If conversions above were
5832 sufficient we should only have 3 or 4 channels here. */
5833 channels
= fn_png_get_channels (png_ptr
, info_ptr
);
5834 eassert (channels
== 3 || channels
== 4);
5836 /* Number of bytes needed for one row of the image. */
5837 row_bytes
= fn_png_get_rowbytes (png_ptr
, info_ptr
);
5839 /* Allocate memory for the image. */
5840 if (min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *rows
< height
5841 || min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *pixels
/ height
< row_bytes
)
5842 memory_full (SIZE_MAX
);
5843 pixels
= (png_byte
*) xmalloc (sizeof *pixels
* row_bytes
* height
);
5844 rows
= (png_byte
**) xmalloc (height
* sizeof *rows
);
5845 for (i
= 0; i
< height
; ++i
)
5846 rows
[i
] = pixels
+ i
* row_bytes
;
5848 /* Read the entire image. */
5849 fn_png_read_image (png_ptr
, rows
);
5850 fn_png_read_end (png_ptr
, info_ptr
);
5857 /* Create an image and pixmap serving as mask if the PNG image
5858 contains an alpha channel. */
5861 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
5862 &mask_img
, &img
->mask
))
5864 x_destroy_x_image (ximg
);
5865 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
5866 img
->pixmap
= NO_PIXMAP
;
5870 /* Fill the X image and mask from PNG data. */
5871 init_color_table ();
5873 for (y
= 0; y
< height
; ++y
)
5875 png_byte
*p
= rows
[y
];
5877 for (x
= 0; x
< width
; ++x
)
5884 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
5885 /* An alpha channel, aka mask channel, associates variable
5886 transparency with an image. Where other image formats
5887 support binary transparency---fully transparent or fully
5888 opaque---PNG allows up to 254 levels of partial transparency.
5889 The PNG library implements partial transparency by combining
5890 the image with a specified background color.
5892 I'm not sure how to handle this here nicely: because the
5893 background on which the image is displayed may change, for
5894 real alpha channel support, it would be necessary to create
5895 a new image for each possible background.
5897 What I'm doing now is that a mask is created if we have
5898 boolean transparency information. Otherwise I'm using
5899 the frame's background color to combine the image with. */
5904 XPutPixel (mask_img
, x
, y
, *p
> 0 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
);
5910 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
5911 /* Set IMG's background color from the PNG image, unless the user
5915 if (fn_png_get_bKGD (png_ptr
, info_ptr
, &bg
))
5917 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
5918 img
->background_valid
= 1;
5922 #ifdef COLOR_TABLE_SUPPORT
5923 /* Remember colors allocated for this image. */
5924 img
->colors
= colors_in_color_table (&img
->ncolors
);
5925 free_color_table ();
5926 #endif /* COLOR_TABLE_SUPPORT */
5929 fn_png_destroy_read_struct (&png_ptr
, &info_ptr
, &end_info
);
5934 img
->height
= height
;
5936 /* Maybe fill in the background field while we have ximg handy.
5937 Casting avoids a GCC warning. */
5938 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
5940 /* Put the image into the pixmap, then free the X image and its buffer. */
5941 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
5942 x_destroy_x_image (ximg
);
5944 /* Same for the mask. */
5947 /* Fill in the background_transparent field while we have the
5948 mask handy. Casting avoids a GCC warning. */
5949 image_background_transparent (img
, f
, (XImagePtr_or_DC
)mask_img
);
5951 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
5952 x_destroy_x_image (mask_img
);
5958 #else /* HAVE_PNG */
5962 png_load (struct frame
*f
, struct image
*img
)
5964 return ns_load_image (f
, img
,
5965 image_spec_value (img
->spec
, QCfile
, NULL
),
5966 image_spec_value (img
->spec
, QCdata
, NULL
));
5968 #endif /* HAVE_NS */
5971 #endif /* !HAVE_PNG */
5975 /***********************************************************************
5977 ***********************************************************************/
5979 #if defined (HAVE_JPEG) || defined (HAVE_NS)
5981 static int jpeg_image_p (Lisp_Object object
);
5982 static int jpeg_load (struct frame
*f
, struct image
*img
);
5984 /* The symbol `jpeg' identifying images of this type. */
5986 static Lisp_Object Qjpeg
;
5988 /* Indices of image specification fields in gs_format, below. */
5990 enum jpeg_keyword_index
5999 JPEG_HEURISTIC_MASK
,
6005 /* Vector of image_keyword structures describing the format
6006 of valid user-defined image specifications. */
6008 static const struct image_keyword jpeg_format
[JPEG_LAST
] =
6010 {":type", IMAGE_SYMBOL_VALUE
, 1},
6011 {":data", IMAGE_STRING_VALUE
, 0},
6012 {":file", IMAGE_STRING_VALUE
, 0},
6013 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6014 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
6015 {":relief", IMAGE_INTEGER_VALUE
, 0},
6016 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6017 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6018 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6019 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
6022 /* Structure describing the image type `jpeg'. */
6024 static struct image_type jpeg_type
=
6033 /* Return non-zero if OBJECT is a valid JPEG image specification. */
6036 jpeg_image_p (Lisp_Object object
)
6038 struct image_keyword fmt
[JPEG_LAST
];
6040 memcpy (fmt
, jpeg_format
, sizeof fmt
);
6042 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
6045 /* Must specify either the :data or :file keyword. */
6046 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
6049 #endif /* HAVE_JPEG || HAVE_NS */
6053 /* Work around a warning about HAVE_STDLIB_H being redefined in
6055 #ifdef HAVE_STDLIB_H
6056 #undef HAVE_STDLIB_H
6057 #endif /* HAVE_STLIB_H */
6059 #if defined (HAVE_NTGUI) && !defined (__WIN32__)
6060 /* In older releases of the jpeg library, jpeglib.h will define boolean
6061 differently depending on __WIN32__, so make sure it is defined. */
6065 #include <jpeglib.h>
6068 #ifdef HAVE_STLIB_H_1
6069 #define HAVE_STDLIB_H 1
6074 /* JPEG library details. */
6075 DEF_IMGLIB_FN (void, jpeg_CreateDecompress
, (j_decompress_ptr
, int, size_t));
6076 DEF_IMGLIB_FN (boolean
, jpeg_start_decompress
, (j_decompress_ptr
));
6077 DEF_IMGLIB_FN (boolean
, jpeg_finish_decompress
, (j_decompress_ptr
));
6078 DEF_IMGLIB_FN (void, jpeg_destroy_decompress
, (j_decompress_ptr
));
6079 DEF_IMGLIB_FN (int, jpeg_read_header
, (j_decompress_ptr
, boolean
));
6080 DEF_IMGLIB_FN (JDIMENSION
, jpeg_read_scanlines
, (j_decompress_ptr
, JSAMPARRAY
, JDIMENSION
));
6081 DEF_IMGLIB_FN (struct jpeg_error_mgr
*, jpeg_std_error
, (struct jpeg_error_mgr
*));
6082 DEF_IMGLIB_FN (boolean
, jpeg_resync_to_restart
, (j_decompress_ptr
, int));
6085 init_jpeg_functions (Lisp_Object libraries
)
6089 if (!(library
= w32_delayed_load (libraries
, Qjpeg
)))
6092 LOAD_IMGLIB_FN (library
, jpeg_finish_decompress
);
6093 LOAD_IMGLIB_FN (library
, jpeg_read_scanlines
);
6094 LOAD_IMGLIB_FN (library
, jpeg_start_decompress
);
6095 LOAD_IMGLIB_FN (library
, jpeg_read_header
);
6096 LOAD_IMGLIB_FN (library
, jpeg_CreateDecompress
);
6097 LOAD_IMGLIB_FN (library
, jpeg_destroy_decompress
);
6098 LOAD_IMGLIB_FN (library
, jpeg_std_error
);
6099 LOAD_IMGLIB_FN (library
, jpeg_resync_to_restart
);
6103 /* Wrapper since we can't directly assign the function pointer
6104 to another function pointer that was declared more completely easily. */
6106 jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo
, int desired
)
6108 return fn_jpeg_resync_to_restart (cinfo
, desired
);
6113 #define fn_jpeg_CreateDecompress(a,b,c) jpeg_create_decompress (a)
6114 #define fn_jpeg_start_decompress jpeg_start_decompress
6115 #define fn_jpeg_finish_decompress jpeg_finish_decompress
6116 #define fn_jpeg_destroy_decompress jpeg_destroy_decompress
6117 #define fn_jpeg_read_header jpeg_read_header
6118 #define fn_jpeg_read_scanlines jpeg_read_scanlines
6119 #define fn_jpeg_std_error jpeg_std_error
6120 #define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart
6122 #endif /* HAVE_NTGUI */
6124 struct my_jpeg_error_mgr
6126 struct jpeg_error_mgr pub
;
6127 jmp_buf setjmp_buffer
;
6131 static _Noreturn
void
6132 my_error_exit (j_common_ptr cinfo
)
6134 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
6135 longjmp (mgr
->setjmp_buffer
, 1);
6139 /* Init source method for JPEG data source manager. Called by
6140 jpeg_read_header() before any data is actually read. See
6141 libjpeg.doc from the JPEG lib distribution. */
6144 our_common_init_source (j_decompress_ptr cinfo
)
6149 /* Method to terminate data source. Called by
6150 jpeg_finish_decompress() after all data has been processed. */
6153 our_common_term_source (j_decompress_ptr cinfo
)
6158 /* Fill input buffer method for JPEG data source manager. Called
6159 whenever more data is needed. We read the whole image in one step,
6160 so this only adds a fake end of input marker at the end. */
6162 static JOCTET our_memory_buffer
[2];
6165 our_memory_fill_input_buffer (j_decompress_ptr cinfo
)
6167 /* Insert a fake EOI marker. */
6168 struct jpeg_source_mgr
*src
= cinfo
->src
;
6170 our_memory_buffer
[0] = (JOCTET
) 0xFF;
6171 our_memory_buffer
[1] = (JOCTET
) JPEG_EOI
;
6173 src
->next_input_byte
= our_memory_buffer
;
6174 src
->bytes_in_buffer
= 2;
6179 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6180 is the JPEG data source manager. */
6183 our_memory_skip_input_data (j_decompress_ptr cinfo
, long int num_bytes
)
6185 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6189 if (num_bytes
> src
->bytes_in_buffer
)
6190 ERREXIT (cinfo
, JERR_INPUT_EOF
);
6192 src
->bytes_in_buffer
-= num_bytes
;
6193 src
->next_input_byte
+= num_bytes
;
6198 /* Set up the JPEG lib for reading an image from DATA which contains
6199 LEN bytes. CINFO is the decompression info structure created for
6200 reading the image. */
6203 jpeg_memory_src (j_decompress_ptr cinfo
, JOCTET
*data
, unsigned int len
)
6205 struct jpeg_source_mgr
*src
;
6207 if (cinfo
->src
== NULL
)
6209 /* First time for this JPEG object? */
6210 cinfo
->src
= (struct jpeg_source_mgr
*)
6211 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6212 sizeof (struct jpeg_source_mgr
));
6213 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6214 src
->next_input_byte
= data
;
6217 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6218 src
->init_source
= our_common_init_source
;
6219 src
->fill_input_buffer
= our_memory_fill_input_buffer
;
6220 src
->skip_input_data
= our_memory_skip_input_data
;
6221 src
->resync_to_restart
= jpeg_resync_to_restart_wrapper
; /* Use default method. */
6222 src
->term_source
= our_common_term_source
;
6223 src
->bytes_in_buffer
= len
;
6224 src
->next_input_byte
= data
;
6228 struct jpeg_stdio_mgr
6230 struct jpeg_source_mgr mgr
;
6237 /* Size of buffer to read JPEG from file.
6238 Not too big, as we want to use alloc_small. */
6239 #define JPEG_STDIO_BUFFER_SIZE 8192
6242 /* Fill input buffer method for JPEG data source manager. Called
6243 whenever more data is needed. The data is read from a FILE *. */
6246 our_stdio_fill_input_buffer (j_decompress_ptr cinfo
)
6248 struct jpeg_stdio_mgr
*src
;
6250 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6255 bytes
= fread (src
->buffer
, 1, JPEG_STDIO_BUFFER_SIZE
, src
->file
);
6257 src
->mgr
.bytes_in_buffer
= bytes
;
6260 WARNMS (cinfo
, JWRN_JPEG_EOF
);
6262 src
->buffer
[0] = (JOCTET
) 0xFF;
6263 src
->buffer
[1] = (JOCTET
) JPEG_EOI
;
6264 src
->mgr
.bytes_in_buffer
= 2;
6266 src
->mgr
.next_input_byte
= src
->buffer
;
6273 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6274 is the JPEG data source manager. */
6277 our_stdio_skip_input_data (j_decompress_ptr cinfo
, long int num_bytes
)
6279 struct jpeg_stdio_mgr
*src
;
6280 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6282 while (num_bytes
> 0 && !src
->finished
)
6284 if (num_bytes
<= src
->mgr
.bytes_in_buffer
)
6286 src
->mgr
.bytes_in_buffer
-= num_bytes
;
6287 src
->mgr
.next_input_byte
+= num_bytes
;
6292 num_bytes
-= src
->mgr
.bytes_in_buffer
;
6293 src
->mgr
.bytes_in_buffer
= 0;
6294 src
->mgr
.next_input_byte
= NULL
;
6296 our_stdio_fill_input_buffer (cinfo
);
6302 /* Set up the JPEG lib for reading an image from a FILE *.
6303 CINFO is the decompression info structure created for
6304 reading the image. */
6307 jpeg_file_src (j_decompress_ptr cinfo
, FILE *fp
)
6309 struct jpeg_stdio_mgr
*src
;
6311 if (cinfo
->src
!= NULL
)
6312 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6315 /* First time for this JPEG object? */
6316 cinfo
->src
= (struct jpeg_source_mgr
*)
6317 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6318 sizeof (struct jpeg_stdio_mgr
));
6319 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6320 src
->buffer
= (JOCTET
*)
6321 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6322 JPEG_STDIO_BUFFER_SIZE
);
6327 src
->mgr
.init_source
= our_common_init_source
;
6328 src
->mgr
.fill_input_buffer
= our_stdio_fill_input_buffer
;
6329 src
->mgr
.skip_input_data
= our_stdio_skip_input_data
;
6330 src
->mgr
.resync_to_restart
= jpeg_resync_to_restart_wrapper
; /* Use default method. */
6331 src
->mgr
.term_source
= our_common_term_source
;
6332 src
->mgr
.bytes_in_buffer
= 0;
6333 src
->mgr
.next_input_byte
= NULL
;
6337 /* Load image IMG for use on frame F. Patterned after example.c
6338 from the JPEG lib. */
6341 jpeg_load (struct frame
*f
, struct image
*img
)
6343 struct jpeg_decompress_struct cinfo
;
6344 struct my_jpeg_error_mgr mgr
;
6345 Lisp_Object file
, specified_file
;
6346 Lisp_Object specified_data
;
6347 FILE * volatile fp
= NULL
;
6349 int row_stride
, x
, y
;
6350 XImagePtr ximg
= NULL
;
6352 unsigned long *colors
;
6355 /* Open the JPEG file. */
6356 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6357 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6359 if (NILP (specified_data
))
6361 file
= x_find_image_file (specified_file
);
6362 if (!STRINGP (file
))
6364 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6368 fp
= fopen (SSDATA (file
), "rb");
6371 image_error ("Cannot open `%s'", file
, Qnil
);
6375 else if (!STRINGP (specified_data
))
6377 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
6381 /* Customize libjpeg's error handling to call my_error_exit when an
6382 error is detected. This function will perform a longjmp. */
6383 cinfo
.err
= fn_jpeg_std_error (&mgr
.pub
);
6384 mgr
.pub
.error_exit
= my_error_exit
;
6386 if ((rc
= setjmp (mgr
.setjmp_buffer
)) != 0)
6390 /* Called from my_error_exit. Display a JPEG error. */
6391 char buf
[JMSG_LENGTH_MAX
];
6392 cinfo
.err
->format_message ((j_common_ptr
) &cinfo
, buf
);
6393 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
6394 build_string (buf
));
6397 /* Close the input file and destroy the JPEG object. */
6399 fclose ((FILE *) fp
);
6400 fn_jpeg_destroy_decompress (&cinfo
);
6402 /* If we already have an XImage, free that. */
6403 x_destroy_x_image (ximg
);
6405 /* Free pixmap and colors. */
6406 x_clear_image (f
, img
);
6410 /* Create the JPEG decompression object. Let it read from fp.
6411 Read the JPEG image header. */
6412 fn_jpeg_CreateDecompress (&cinfo
, JPEG_LIB_VERSION
, sizeof (cinfo
));
6414 if (NILP (specified_data
))
6415 jpeg_file_src (&cinfo
, (FILE *) fp
);
6417 jpeg_memory_src (&cinfo
, SDATA (specified_data
),
6418 SBYTES (specified_data
));
6420 fn_jpeg_read_header (&cinfo
, 1);
6422 /* Customize decompression so that color quantization will be used.
6423 Start decompression. */
6424 cinfo
.quantize_colors
= 1;
6425 fn_jpeg_start_decompress (&cinfo
);
6426 width
= img
->width
= cinfo
.output_width
;
6427 height
= img
->height
= cinfo
.output_height
;
6429 if (!check_image_size (f
, width
, height
))
6431 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
6432 longjmp (mgr
.setjmp_buffer
, 2);
6435 /* Create X image and pixmap. */
6436 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
6437 longjmp (mgr
.setjmp_buffer
, 2);
6439 /* Allocate colors. When color quantization is used,
6440 cinfo.actual_number_of_colors has been set with the number of
6441 colors generated, and cinfo.colormap is a two-dimensional array
6442 of color indices in the range 0..cinfo.actual_number_of_colors.
6443 No more than 255 colors will be generated. */
6447 if (cinfo
.out_color_components
> 2)
6448 ir
= 0, ig
= 1, ib
= 2;
6449 else if (cinfo
.out_color_components
> 1)
6450 ir
= 0, ig
= 1, ib
= 0;
6452 ir
= 0, ig
= 0, ib
= 0;
6454 /* Use the color table mechanism because it handles colors that
6455 cannot be allocated nicely. Such colors will be replaced with
6456 a default color, and we don't have to care about which colors
6457 can be freed safely, and which can't. */
6458 init_color_table ();
6459 colors
= (unsigned long *) alloca (cinfo
.actual_number_of_colors
6462 for (i
= 0; i
< cinfo
.actual_number_of_colors
; ++i
)
6464 /* Multiply RGB values with 255 because X expects RGB values
6465 in the range 0..0xffff. */
6466 int r
= cinfo
.colormap
[ir
][i
] << 8;
6467 int g
= cinfo
.colormap
[ig
][i
] << 8;
6468 int b
= cinfo
.colormap
[ib
][i
] << 8;
6469 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
6472 #ifdef COLOR_TABLE_SUPPORT
6473 /* Remember those colors actually allocated. */
6474 img
->colors
= colors_in_color_table (&img
->ncolors
);
6475 free_color_table ();
6476 #endif /* COLOR_TABLE_SUPPORT */
6480 row_stride
= width
* cinfo
.output_components
;
6481 buffer
= cinfo
.mem
->alloc_sarray ((j_common_ptr
) &cinfo
, JPOOL_IMAGE
,
6483 for (y
= 0; y
< height
; ++y
)
6485 fn_jpeg_read_scanlines (&cinfo
, buffer
, 1);
6486 for (x
= 0; x
< cinfo
.output_width
; ++x
)
6487 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
6491 fn_jpeg_finish_decompress (&cinfo
);
6492 fn_jpeg_destroy_decompress (&cinfo
);
6494 fclose ((FILE *) fp
);
6496 /* Maybe fill in the background field while we have ximg handy. */
6497 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6498 /* Casting avoids a GCC warning. */
6499 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6501 /* Put the image into the pixmap. */
6502 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6503 x_destroy_x_image (ximg
);
6507 #else /* HAVE_JPEG */
6511 jpeg_load (struct frame
*f
, struct image
*img
)
6513 return ns_load_image (f
, img
,
6514 image_spec_value (img
->spec
, QCfile
, NULL
),
6515 image_spec_value (img
->spec
, QCdata
, NULL
));
6517 #endif /* HAVE_NS */
6519 #endif /* !HAVE_JPEG */
6523 /***********************************************************************
6525 ***********************************************************************/
6527 #if defined (HAVE_TIFF) || defined (HAVE_NS)
6529 static int tiff_image_p (Lisp_Object object
);
6530 static int tiff_load (struct frame
*f
, struct image
*img
);
6532 /* The symbol `tiff' identifying images of this type. */
6534 static Lisp_Object Qtiff
;
6536 /* Indices of image specification fields in tiff_format, below. */
6538 enum tiff_keyword_index
6547 TIFF_HEURISTIC_MASK
,
6554 /* Vector of image_keyword structures describing the format
6555 of valid user-defined image specifications. */
6557 static const struct image_keyword tiff_format
[TIFF_LAST
] =
6559 {":type", IMAGE_SYMBOL_VALUE
, 1},
6560 {":data", IMAGE_STRING_VALUE
, 0},
6561 {":file", IMAGE_STRING_VALUE
, 0},
6562 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6563 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
6564 {":relief", IMAGE_INTEGER_VALUE
, 0},
6565 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6566 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6567 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6568 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
6569 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0}
6572 /* Structure describing the image type `tiff'. */
6574 static struct image_type tiff_type
=
6583 /* Return non-zero if OBJECT is a valid TIFF image specification. */
6586 tiff_image_p (Lisp_Object object
)
6588 struct image_keyword fmt
[TIFF_LAST
];
6589 memcpy (fmt
, tiff_format
, sizeof fmt
);
6591 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
6594 /* Must specify either the :data or :file keyword. */
6595 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
6598 #endif /* HAVE_TIFF || HAVE_NS */
6606 /* TIFF library details. */
6607 DEF_IMGLIB_FN (TIFFErrorHandler
, TIFFSetErrorHandler
, (TIFFErrorHandler
));
6608 DEF_IMGLIB_FN (TIFFErrorHandler
, TIFFSetWarningHandler
, (TIFFErrorHandler
));
6609 DEF_IMGLIB_FN (TIFF
*, TIFFOpen
, (const char *, const char *));
6610 DEF_IMGLIB_FN (TIFF
*, TIFFClientOpen
, (const char *, const char *, thandle_t
,
6611 TIFFReadWriteProc
, TIFFReadWriteProc
,
6612 TIFFSeekProc
, TIFFCloseProc
, TIFFSizeProc
,
6613 TIFFMapFileProc
, TIFFUnmapFileProc
));
6614 DEF_IMGLIB_FN (int, TIFFGetField
, (TIFF
*, ttag_t
, ...));
6615 DEF_IMGLIB_FN (int, TIFFReadRGBAImage
, (TIFF
*, uint32
, uint32
, uint32
*, int));
6616 DEF_IMGLIB_FN (void, TIFFClose
, (TIFF
*));
6617 DEF_IMGLIB_FN (int, TIFFSetDirectory
, (TIFF
*, tdir_t
));
6620 init_tiff_functions (Lisp_Object libraries
)
6624 if (!(library
= w32_delayed_load (libraries
, Qtiff
)))
6627 LOAD_IMGLIB_FN (library
, TIFFSetErrorHandler
);
6628 LOAD_IMGLIB_FN (library
, TIFFSetWarningHandler
);
6629 LOAD_IMGLIB_FN (library
, TIFFOpen
);
6630 LOAD_IMGLIB_FN (library
, TIFFClientOpen
);
6631 LOAD_IMGLIB_FN (library
, TIFFGetField
);
6632 LOAD_IMGLIB_FN (library
, TIFFReadRGBAImage
);
6633 LOAD_IMGLIB_FN (library
, TIFFClose
);
6634 LOAD_IMGLIB_FN (library
, TIFFSetDirectory
);
6640 #define fn_TIFFSetErrorHandler TIFFSetErrorHandler
6641 #define fn_TIFFSetWarningHandler TIFFSetWarningHandler
6642 #define fn_TIFFOpen TIFFOpen
6643 #define fn_TIFFClientOpen TIFFClientOpen
6644 #define fn_TIFFGetField TIFFGetField
6645 #define fn_TIFFReadRGBAImage TIFFReadRGBAImage
6646 #define fn_TIFFClose TIFFClose
6647 #define fn_TIFFSetDirectory TIFFSetDirectory
6648 #endif /* HAVE_NTGUI */
6651 /* Reading from a memory buffer for TIFF images Based on the PNG
6652 memory source, but we have to provide a lot of extra functions.
6655 We really only need to implement read and seek, but I am not
6656 convinced that the TIFF library is smart enough not to destroy
6657 itself if we only hand it the function pointers we need to
6662 unsigned char *bytes
;
6669 tiff_read_from_memory (thandle_t data
, tdata_t buf
, tsize_t size
)
6671 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6673 size
= min (size
, src
->len
- src
->index
);
6674 memcpy (buf
, src
->bytes
+ src
->index
, size
);
6680 tiff_write_from_memory (thandle_t data
, tdata_t buf
, tsize_t size
)
6686 tiff_seek_in_memory (thandle_t data
, toff_t off
, int whence
)
6688 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6693 case SEEK_SET
: /* Go from beginning of source. */
6697 case SEEK_END
: /* Go from end of source. */
6698 idx
= src
->len
+ off
;
6701 case SEEK_CUR
: /* Go from current position. */
6702 idx
= src
->index
+ off
;
6705 default: /* Invalid `whence'. */
6709 if (idx
> src
->len
|| idx
< 0)
6717 tiff_close_memory (thandle_t data
)
6724 tiff_mmap_memory (thandle_t data
, tdata_t
*pbase
, toff_t
*psize
)
6726 /* It is already _IN_ memory. */
6731 tiff_unmap_memory (thandle_t data
, tdata_t base
, toff_t size
)
6733 /* We don't need to do this. */
6737 tiff_size_of_memory (thandle_t data
)
6739 return ((tiff_memory_source
*) data
)->len
;
6742 /* GCC 3.x on x86 Windows targets has a bug that triggers an internal
6743 compiler error compiling tiff_handler, see Bugzilla bug #17406
6744 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17406). Declaring
6745 this function as external works around that problem. */
6746 #if defined (__MINGW32__) && __GNUC__ == 3
6747 # define MINGW_STATIC
6749 # define MINGW_STATIC static
6753 tiff_handler (const char *, const char *, const char *, va_list)
6754 ATTRIBUTE_FORMAT_PRINTF (3, 0);
6756 tiff_handler (const char *log_format
, const char *title
,
6757 const char *format
, va_list ap
)
6759 /* doprnt is not suitable here, as TIFF handlers are called from
6760 libtiff and are passed arbitrary printf directives. Instead, use
6761 vsnprintf, taking care to be portable to nonstandard environments
6762 where vsnprintf returns -1 on buffer overflow. Since it's just a
6763 log entry, it's OK to truncate it. */
6765 int len
= vsnprintf (buf
, sizeof buf
, format
, ap
);
6766 add_to_log (log_format
, build_string (title
),
6767 make_string (buf
, max (0, min (len
, sizeof buf
- 1))));
6771 static void tiff_error_handler (const char *, const char *, va_list)
6772 ATTRIBUTE_FORMAT_PRINTF (2, 0);
6774 tiff_error_handler (const char *title
, const char *format
, va_list ap
)
6776 tiff_handler ("TIFF error: %s %s", title
, format
, ap
);
6780 static void tiff_warning_handler (const char *, const char *, va_list)
6781 ATTRIBUTE_FORMAT_PRINTF (2, 0);
6783 tiff_warning_handler (const char *title
, const char *format
, va_list ap
)
6785 tiff_handler ("TIFF warning: %s %s", title
, format
, ap
);
6789 /* Load TIFF image IMG for use on frame F. Value is non-zero if
6793 tiff_load (struct frame
*f
, struct image
*img
)
6795 Lisp_Object file
, specified_file
;
6796 Lisp_Object specified_data
;
6798 int width
, height
, x
, y
, count
;
6802 tiff_memory_source memsrc
;
6805 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6806 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6808 fn_TIFFSetErrorHandler ((TIFFErrorHandler
) tiff_error_handler
);
6809 fn_TIFFSetWarningHandler ((TIFFErrorHandler
) tiff_warning_handler
);
6811 if (NILP (specified_data
))
6813 /* Read from a file */
6814 file
= x_find_image_file (specified_file
);
6815 if (!STRINGP (file
))
6817 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6821 /* Try to open the image file. */
6822 tiff
= fn_TIFFOpen (SSDATA (file
), "r");
6825 image_error ("Cannot open `%s'", file
, Qnil
);
6831 if (!STRINGP (specified_data
))
6833 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
6837 /* Memory source! */
6838 memsrc
.bytes
= SDATA (specified_data
);
6839 memsrc
.len
= SBYTES (specified_data
);
6842 tiff
= fn_TIFFClientOpen ("memory_source", "r", (thandle_t
)&memsrc
,
6843 tiff_read_from_memory
,
6844 tiff_write_from_memory
,
6845 tiff_seek_in_memory
,
6847 tiff_size_of_memory
,
6853 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
6858 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
6859 if (INTEGERP (image
))
6861 EMACS_INT ino
= XFASTINT (image
);
6862 if (! (TYPE_MINIMUM (tdir_t
) <= ino
&& ino
<= TYPE_MAXIMUM (tdir_t
)
6863 && fn_TIFFSetDirectory (tiff
, ino
)))
6865 image_error ("Invalid image number `%s' in image `%s'",
6867 fn_TIFFClose (tiff
);
6872 /* Get width and height of the image, and allocate a raster buffer
6873 of width x height 32-bit values. */
6874 fn_TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
6875 fn_TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
6877 if (!check_image_size (f
, width
, height
))
6879 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
6880 fn_TIFFClose (tiff
);
6884 /* Create the X image and pixmap. */
6885 if (! (height
<= min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *buf
/ width
6886 && x_create_x_image_and_pixmap (f
, width
, height
, 0,
6887 &ximg
, &img
->pixmap
)))
6889 fn_TIFFClose (tiff
);
6893 buf
= (uint32
*) xmalloc (sizeof *buf
* width
* height
);
6895 rc
= fn_TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
6897 /* Count the number of images in the file. */
6898 for (count
= 1; fn_TIFFSetDirectory (tiff
, count
); count
++)
6902 img
->lisp_data
= Fcons (Qcount
,
6903 Fcons (make_number (count
),
6906 fn_TIFFClose (tiff
);
6909 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
6914 /* Initialize the color table. */
6915 init_color_table ();
6917 /* Process the pixel raster. Origin is in the lower-left corner. */
6918 for (y
= 0; y
< height
; ++y
)
6920 uint32
*row
= buf
+ y
* width
;
6922 for (x
= 0; x
< width
; ++x
)
6924 uint32 abgr
= row
[x
];
6925 int r
= TIFFGetR (abgr
) << 8;
6926 int g
= TIFFGetG (abgr
) << 8;
6927 int b
= TIFFGetB (abgr
) << 8;
6928 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
6932 #ifdef COLOR_TABLE_SUPPORT
6933 /* Remember the colors allocated for the image. Free the color table. */
6934 img
->colors
= colors_in_color_table (&img
->ncolors
);
6935 free_color_table ();
6936 #endif /* COLOR_TABLE_SUPPORT */
6939 img
->height
= height
;
6941 /* Maybe fill in the background field while we have ximg handy. */
6942 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6943 /* Casting avoids a GCC warning on W32. */
6944 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6946 /* Put the image into the pixmap, then free the X image and its buffer. */
6947 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6948 x_destroy_x_image (ximg
);
6954 #else /* HAVE_TIFF */
6958 tiff_load (struct frame
*f
, struct image
*img
)
6960 return ns_load_image (f
, img
,
6961 image_spec_value (img
->spec
, QCfile
, NULL
),
6962 image_spec_value (img
->spec
, QCdata
, NULL
));
6964 #endif /* HAVE_NS */
6966 #endif /* !HAVE_TIFF */
6970 /***********************************************************************
6972 ***********************************************************************/
6974 #if defined (HAVE_GIF) || defined (HAVE_NS)
6976 static int gif_image_p (Lisp_Object object
);
6977 static int gif_load (struct frame
*f
, struct image
*img
);
6978 static void gif_clear_image (struct frame
*f
, struct image
*img
);
6980 /* The symbol `gif' identifying images of this type. */
6982 static Lisp_Object Qgif
;
6984 /* Indices of image specification fields in gif_format, below. */
6986 enum gif_keyword_index
7002 /* Vector of image_keyword structures describing the format
7003 of valid user-defined image specifications. */
7005 static const struct image_keyword gif_format
[GIF_LAST
] =
7007 {":type", IMAGE_SYMBOL_VALUE
, 1},
7008 {":data", IMAGE_STRING_VALUE
, 0},
7009 {":file", IMAGE_STRING_VALUE
, 0},
7010 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7011 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
7012 {":relief", IMAGE_INTEGER_VALUE
, 0},
7013 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7014 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7015 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7016 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7017 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7020 /* Structure describing the image type `gif'. */
7022 static struct image_type gif_type
=
7031 /* Free X resources of GIF image IMG which is used on frame F. */
7034 gif_clear_image (struct frame
*f
, struct image
*img
)
7036 img
->lisp_data
= Qnil
;
7037 x_clear_image (f
, img
);
7040 /* Return non-zero if OBJECT is a valid GIF image specification. */
7043 gif_image_p (Lisp_Object object
)
7045 struct image_keyword fmt
[GIF_LAST
];
7046 memcpy (fmt
, gif_format
, sizeof fmt
);
7048 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
7051 /* Must specify either the :data or :file keyword. */
7052 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
7055 #endif /* HAVE_GIF */
7059 #if defined (HAVE_NTGUI)
7060 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
7061 Undefine before redefining to avoid a preprocessor warning. */
7065 /* avoid conflict with QuickdrawText.h */
7066 #define DrawText gif_DrawText
7067 #include <gif_lib.h>
7070 #else /* HAVE_NTGUI */
7072 #include <gif_lib.h>
7074 #endif /* HAVE_NTGUI */
7079 /* GIF library details. */
7080 DEF_IMGLIB_FN (int, DGifCloseFile
, (GifFileType
*));
7081 DEF_IMGLIB_FN (int, DGifSlurp
, (GifFileType
*));
7082 DEF_IMGLIB_FN (GifFileType
*, DGifOpen
, (void *, InputFunc
));
7083 DEF_IMGLIB_FN (GifFileType
*, DGifOpenFileName
, (const char *));
7086 init_gif_functions (Lisp_Object libraries
)
7090 if (!(library
= w32_delayed_load (libraries
, Qgif
)))
7093 LOAD_IMGLIB_FN (library
, DGifCloseFile
);
7094 LOAD_IMGLIB_FN (library
, DGifSlurp
);
7095 LOAD_IMGLIB_FN (library
, DGifOpen
);
7096 LOAD_IMGLIB_FN (library
, DGifOpenFileName
);
7102 #define fn_DGifCloseFile DGifCloseFile
7103 #define fn_DGifSlurp DGifSlurp
7104 #define fn_DGifOpen DGifOpen
7105 #define fn_DGifOpenFileName DGifOpenFileName
7107 #endif /* HAVE_NTGUI */
7109 /* Reading a GIF image from memory
7110 Based on the PNG memory stuff to a certain extent. */
7114 unsigned char *bytes
;
7120 /* Make the current memory source available to gif_read_from_memory.
7121 It's done this way because not all versions of libungif support
7122 a UserData field in the GifFileType structure. */
7123 static gif_memory_source
*current_gif_memory_src
;
7126 gif_read_from_memory (GifFileType
*file
, GifByteType
*buf
, int len
)
7128 gif_memory_source
*src
= current_gif_memory_src
;
7130 if (len
> src
->len
- src
->index
)
7133 memcpy (buf
, src
->bytes
+ src
->index
, len
);
7139 /* Load GIF image IMG for use on frame F. Value is non-zero if
7142 static const int interlace_start
[] = {0, 4, 2, 1};
7143 static const int interlace_increment
[] = {8, 8, 4, 2};
7145 #define GIF_LOCAL_DESCRIPTOR_EXTENSION 249
7148 gif_load (struct frame
*f
, struct image
*img
)
7151 int rc
, width
, height
, x
, y
, i
, j
;
7153 ColorMapObject
*gif_color_map
;
7154 unsigned long pixel_colors
[256];
7156 gif_memory_source memsrc
;
7157 Lisp_Object specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
7158 Lisp_Object specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7159 Lisp_Object specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7160 unsigned long bgcolor
= 0;
7163 if (NILP (specified_data
))
7165 file
= x_find_image_file (specified_file
);
7166 if (!STRINGP (file
))
7168 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7172 /* Open the GIF file. */
7173 gif
= fn_DGifOpenFileName (SSDATA (file
));
7176 image_error ("Cannot open `%s'", file
, Qnil
);
7182 if (!STRINGP (specified_data
))
7184 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
7188 /* Read from memory! */
7189 current_gif_memory_src
= &memsrc
;
7190 memsrc
.bytes
= SDATA (specified_data
);
7191 memsrc
.len
= SBYTES (specified_data
);
7194 gif
= fn_DGifOpen (&memsrc
, gif_read_from_memory
);
7197 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
7202 /* Before reading entire contents, check the declared image size. */
7203 if (!check_image_size (f
, gif
->SWidth
, gif
->SHeight
))
7205 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7206 fn_DGifCloseFile (gif
);
7210 /* Read entire contents. */
7211 rc
= fn_DGifSlurp (gif
);
7212 if (rc
== GIF_ERROR
|| gif
->ImageCount
<= 0)
7214 image_error ("Error reading `%s'", img
->spec
, Qnil
);
7215 fn_DGifCloseFile (gif
);
7219 /* Which sub-image are we to display? */
7221 Lisp_Object image_number
= image_spec_value (img
->spec
, QCindex
, NULL
);
7222 idx
= INTEGERP (image_number
) ? XFASTINT (image_number
) : 0;
7223 if (idx
< 0 || idx
>= gif
->ImageCount
)
7225 image_error ("Invalid image number `%s' in image `%s'",
7226 image_number
, img
->spec
);
7227 fn_DGifCloseFile (gif
);
7232 width
= img
->width
= gif
->SWidth
;
7233 height
= img
->height
= gif
->SHeight
;
7235 img
->corners
[TOP_CORNER
] = gif
->SavedImages
[0].ImageDesc
.Top
;
7236 img
->corners
[LEFT_CORNER
] = gif
->SavedImages
[0].ImageDesc
.Left
;
7237 img
->corners
[BOT_CORNER
]
7238 = img
->corners
[TOP_CORNER
] + gif
->SavedImages
[0].ImageDesc
.Height
;
7239 img
->corners
[RIGHT_CORNER
]
7240 = img
->corners
[LEFT_CORNER
] + gif
->SavedImages
[0].ImageDesc
.Width
;
7242 if (!check_image_size (f
, width
, height
))
7244 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7245 fn_DGifCloseFile (gif
);
7249 /* Create the X image and pixmap. */
7250 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
7252 fn_DGifCloseFile (gif
);
7256 /* Clear the part of the screen image not covered by the image.
7257 Full animated GIF support requires more here (see the gif89 spec,
7258 disposal methods). Let's simply assume that the part not covered
7259 by a sub-image is in the frame's background color. */
7260 for (y
= 0; y
< img
->corners
[TOP_CORNER
]; ++y
)
7261 for (x
= 0; x
< width
; ++x
)
7262 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7264 for (y
= img
->corners
[BOT_CORNER
]; y
< height
; ++y
)
7265 for (x
= 0; x
< width
; ++x
)
7266 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7268 for (y
= img
->corners
[TOP_CORNER
]; y
< img
->corners
[BOT_CORNER
]; ++y
)
7270 for (x
= 0; x
< img
->corners
[LEFT_CORNER
]; ++x
)
7271 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7272 for (x
= img
->corners
[RIGHT_CORNER
]; x
< width
; ++x
)
7273 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7276 /* Read the GIF image into the X image. */
7278 /* FIXME: With the current implementation, loading an animated gif
7279 is quadratic in the number of animation frames, since each frame
7280 is a separate struct image. We must provide a way for a single
7281 gif_load call to construct and save all animation frames. */
7283 init_color_table ();
7284 if (STRINGP (specified_bg
))
7285 bgcolor
= x_alloc_image_color (f
, img
, specified_bg
,
7286 FRAME_BACKGROUND_PIXEL (f
));
7287 for (j
= 0; j
<= idx
; ++j
)
7289 /* We use a local variable `raster' here because RasterBits is a
7290 char *, which invites problems with bytes >= 0x80. */
7291 struct SavedImage
*subimage
= gif
->SavedImages
+ j
;
7292 unsigned char *raster
= (unsigned char *) subimage
->RasterBits
;
7293 int transparency_color_index
= -1;
7295 int subimg_width
= subimage
->ImageDesc
.Width
;
7296 int subimg_height
= subimage
->ImageDesc
.Height
;
7297 int subimg_top
= subimage
->ImageDesc
.Top
;
7298 int subimg_left
= subimage
->ImageDesc
.Left
;
7300 /* Find the Graphic Control Extension block for this sub-image.
7301 Extract the disposal method and transparency color. */
7302 for (i
= 0; i
< subimage
->ExtensionBlockCount
; i
++)
7304 ExtensionBlock
*extblock
= subimage
->ExtensionBlocks
+ i
;
7306 if ((extblock
->Function
== GIF_LOCAL_DESCRIPTOR_EXTENSION
)
7307 && extblock
->ByteCount
== 4
7308 && extblock
->Bytes
[0] & 1)
7310 /* From gif89a spec: 1 = "keep in place", 2 = "restore
7311 to background". Treat any other value like 2. */
7312 disposal
= (extblock
->Bytes
[0] >> 2) & 7;
7313 transparency_color_index
= (unsigned char) extblock
->Bytes
[3];
7318 /* We can't "keep in place" the first subimage. */
7322 /* For disposal == 0, the spec says "No disposal specified. The
7323 decoder is not required to take any action." In practice, it
7324 seems we need to treat this like "keep in place", see e.g.
7325 http://upload.wikimedia.org/wikipedia/commons/3/37/Clock.gif */
7329 /* Allocate subimage colors. */
7330 memset (pixel_colors
, 0, sizeof pixel_colors
);
7331 gif_color_map
= subimage
->ImageDesc
.ColorMap
;
7333 gif_color_map
= gif
->SColorMap
;
7336 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
7338 if (transparency_color_index
== i
)
7339 pixel_colors
[i
] = STRINGP (specified_bg
)
7340 ? bgcolor
: FRAME_BACKGROUND_PIXEL (f
);
7343 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
7344 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
7345 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
7346 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
7350 /* Apply the pixel values. */
7351 if (gif
->SavedImages
[j
].ImageDesc
.Interlace
)
7355 for (y
= 0, row
= interlace_start
[0], pass
= 0;
7357 y
++, row
+= interlace_increment
[pass
])
7359 if (row
>= subimg_height
)
7361 row
= interlace_start
[++pass
];
7362 while (row
>= subimg_height
)
7363 row
= interlace_start
[++pass
];
7366 for (x
= 0; x
< subimg_width
; x
++)
7368 int c
= raster
[y
* subimg_width
+ x
];
7369 if (transparency_color_index
!= c
|| disposal
!= 1)
7370 XPutPixel (ximg
, x
+ subimg_left
, row
+ subimg_top
,
7377 for (y
= 0; y
< subimg_height
; ++y
)
7378 for (x
= 0; x
< subimg_width
; ++x
)
7380 int c
= raster
[y
* subimg_width
+ x
];
7381 if (transparency_color_index
!= c
|| disposal
!= 1)
7382 XPutPixel (ximg
, x
+ subimg_left
, y
+ subimg_top
,
7388 #ifdef COLOR_TABLE_SUPPORT
7389 img
->colors
= colors_in_color_table (&img
->ncolors
);
7390 free_color_table ();
7391 #endif /* COLOR_TABLE_SUPPORT */
7393 /* Save GIF image extension data for `image-metadata'.
7394 Format is (count IMAGES extension-data (FUNCTION "BYTES" ...)). */
7395 img
->lisp_data
= Qnil
;
7396 if (gif
->SavedImages
[idx
].ExtensionBlockCount
> 0)
7399 ExtensionBlock
*ext
= gif
->SavedImages
[idx
].ExtensionBlocks
;
7400 for (i
= 0; i
< gif
->SavedImages
[idx
].ExtensionBlockCount
; i
++, ext
++)
7401 /* Append (... FUNCTION "BYTES") */
7404 = Fcons (make_number (ext
->Function
),
7405 Fcons (make_unibyte_string (ext
->Bytes
, ext
->ByteCount
),
7407 if (ext
->Function
== GIF_LOCAL_DESCRIPTOR_EXTENSION
7408 && ext
->ByteCount
== 4)
7410 delay
= ext
->Bytes
[2] << CHAR_BIT
;
7411 delay
|= ext
->Bytes
[1];
7414 img
->lisp_data
= Fcons (Qextension_data
,
7415 Fcons (img
->lisp_data
, Qnil
));
7419 Fcons (make_float (delay
/ 100.0),
7423 if (gif
->ImageCount
> 1)
7424 img
->lisp_data
= Fcons (Qcount
,
7425 Fcons (make_number (gif
->ImageCount
),
7428 fn_DGifCloseFile (gif
);
7430 /* Maybe fill in the background field while we have ximg handy. */
7431 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7432 /* Casting avoids a GCC warning. */
7433 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
7435 /* Put the image into the pixmap, then free the X image and its buffer. */
7436 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7437 x_destroy_x_image (ximg
);
7442 #else /* !HAVE_GIF */
7446 gif_load (struct frame
*f
, struct image
*img
)
7448 return ns_load_image (f
, img
,
7449 image_spec_value (img
->spec
, QCfile
, NULL
),
7450 image_spec_value (img
->spec
, QCdata
, NULL
));
7452 #endif /* HAVE_NS */
7454 #endif /* HAVE_GIF */
7457 /***********************************************************************
7459 ***********************************************************************/
7460 #if defined (HAVE_IMAGEMAGICK)
7462 static Lisp_Object Qimagemagick
;
7464 static int imagemagick_image_p (Lisp_Object
);
7465 static int imagemagick_load (struct frame
*, struct image
*);
7466 static void imagemagick_clear_image (struct frame
*, struct image
*);
7468 /* Indices of image specification fields in imagemagick_format. */
7470 enum imagemagick_keyword_index
7478 IMAGEMAGICK_ALGORITHM
,
7479 IMAGEMAGICK_HEURISTIC_MASK
,
7481 IMAGEMAGICK_BACKGROUND
,
7484 IMAGEMAGICK_ROTATION
,
7489 /* Vector of image_keyword structures describing the format
7490 of valid user-defined image specifications. */
7492 static struct image_keyword imagemagick_format
[IMAGEMAGICK_LAST
] =
7494 {":type", IMAGE_SYMBOL_VALUE
, 1},
7495 {":data", IMAGE_STRING_VALUE
, 0},
7496 {":file", IMAGE_STRING_VALUE
, 0},
7497 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7498 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
7499 {":relief", IMAGE_INTEGER_VALUE
, 0},
7500 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7501 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7502 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7503 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
7504 {":height", IMAGE_INTEGER_VALUE
, 0},
7505 {":width", IMAGE_INTEGER_VALUE
, 0},
7506 {":rotation", IMAGE_NUMBER_VALUE
, 0},
7507 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
7510 /* Structure describing the image type for any image handled via
7513 static struct image_type imagemagick_type
=
7516 imagemagick_image_p
,
7518 imagemagick_clear_image
,
7522 /* Free X resources of imagemagick image IMG which is used on frame F. */
7525 imagemagick_clear_image (struct frame
*f
,
7528 x_clear_image (f
, img
);
7531 /* Return non-zero if OBJECT is a valid IMAGEMAGICK image specification. Do
7532 this by calling parse_image_spec and supplying the keywords that
7533 identify the IMAGEMAGICK format. */
7536 imagemagick_image_p (Lisp_Object object
)
7538 struct image_keyword fmt
[IMAGEMAGICK_LAST
];
7539 memcpy (fmt
, imagemagick_format
, sizeof fmt
);
7541 if (!parse_image_spec (object
, fmt
, IMAGEMAGICK_LAST
, Qimagemagick
))
7544 /* Must specify either the :data or :file keyword. */
7545 return fmt
[IMAGEMAGICK_FILE
].count
+ fmt
[IMAGEMAGICK_DATA
].count
== 1;
7548 /* The GIF library also defines DrawRectangle, but its never used in Emacs.
7549 Therefore rename the function so it doesn't collide with ImageMagick. */
7550 #define DrawRectangle DrawRectangleGif
7551 #include <wand/MagickWand.h>
7553 /* ImageMagick 6.5.3 through 6.6.5 hid PixelGetMagickColor for some reason.
7554 Emacs seems to work fine with the hidden version, so unhide it. */
7555 #include <magick/version.h>
7556 #if 0x653 <= MagickLibVersion && MagickLibVersion <= 0x665
7557 extern WandExport
void PixelGetMagickColor (const PixelWand
*,
7558 MagickPixelPacket
*);
7561 /* Log ImageMagick error message.
7562 Useful when a ImageMagick function returns the status `MagickFalse'. */
7565 imagemagick_error (MagickWand
*wand
)
7568 ExceptionType severity
;
7570 description
= MagickGetException (wand
, &severity
);
7571 image_error ("ImageMagick error: %s",
7572 build_string (description
),
7574 description
= (char *) MagickRelinquishMemory (description
);
7577 /* Helper function for imagemagick_load, which does the actual loading
7578 given contents and size, apart from frame and image structures,
7579 passed from imagemagick_load. Uses librimagemagick to do most of
7580 the image processing.
7582 F is a pointer to the Emacs frame; IMG to the image structure to
7583 prepare; CONTENTS is the string containing the IMAGEMAGICK data to
7584 be parsed; SIZE is the number of bytes of data; and FILENAME is
7585 either the file name or the image data.
7587 Return non-zero if successful. */
7590 imagemagick_load_image (struct frame
*f
, struct image
*img
,
7591 unsigned char *contents
, unsigned int size
,
7594 size_t width
, height
;
7595 MagickBooleanType status
;
7598 MagickWand
*image_wand
;
7599 MagickWand
*ping_wand
;
7600 PixelIterator
*iterator
;
7601 PixelWand
**pixels
, *bg_wand
= NULL
;
7602 MagickPixelPacket pixel
;
7607 int desired_width
, desired_height
;
7611 /* Handle image index for image types who can contain more than one image.
7612 Interface :index is same as for GIF. First we "ping" the image to see how
7613 many sub-images it contains. Pinging is faster than loading the image to
7614 find out things about it. */
7616 /* Initialize the imagemagick environment. */
7617 MagickWandGenesis ();
7618 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
7619 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
7620 ping_wand
= NewMagickWand ();
7621 /* MagickSetResolution (ping_wand, 2, 2); (Bug#10112) */
7624 ? MagickPingImage (ping_wand
, filename
)
7625 : MagickPingImageBlob (ping_wand
, contents
, size
);
7627 if (status
== MagickFalse
)
7629 imagemagick_error (ping_wand
);
7630 DestroyMagickWand (ping_wand
);
7634 if (ino
< 0 || ino
>= MagickGetNumberImages (ping_wand
))
7636 image_error ("Invalid image number `%s' in image `%s'",
7638 DestroyMagickWand (ping_wand
);
7642 if (MagickGetNumberImages (ping_wand
) > 1)
7645 Fcons (make_number (MagickGetNumberImages (ping_wand
)),
7648 DestroyMagickWand (ping_wand
);
7650 /* Now we know how many images are inside the file. If it's not a
7651 bundle, the number is one. Load the image data. */
7653 image_wand
= NewMagickWand ();
7656 ? MagickReadImage (image_wand
, filename
)
7657 : MagickReadImageBlob (image_wand
, contents
, size
))
7660 imagemagick_error (image_wand
);
7661 goto imagemagick_error
;
7664 /* Retrieve the frame's background color, for use later. */
7667 Lisp_Object specified_bg
;
7669 specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
7670 if (!STRINGP (specified_bg
)
7671 || !x_defined_color (f
, SSDATA (specified_bg
), &bgcolor
, 0))
7674 bgcolor
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
7675 x_query_color (f
, &bgcolor
);
7677 ns_query_color (FRAME_BACKGROUND_COLOR (f
), &bgcolor
, 1);
7681 bg_wand
= NewPixelWand ();
7682 PixelSetRed (bg_wand
, (double) bgcolor
.red
/ 65535);
7683 PixelSetGreen (bg_wand
, (double) bgcolor
.green
/ 65535);
7684 PixelSetBlue (bg_wand
, (double) bgcolor
.blue
/ 65535);
7687 /* If width and/or height is set in the display spec assume we want
7688 to scale to those values. If either h or w is unspecified, the
7689 unspecified should be calculated from the specified to preserve
7691 value
= image_spec_value (img
->spec
, QCwidth
, NULL
);
7692 desired_width
= (INTEGERP (value
) ? XFASTINT (value
) : -1);
7693 value
= image_spec_value (img
->spec
, QCheight
, NULL
);
7694 desired_height
= (INTEGERP (value
) ? XFASTINT (value
) : -1);
7696 height
= MagickGetImageHeight (image_wand
);
7697 width
= MagickGetImageWidth (image_wand
);
7699 if (desired_width
!= -1 && desired_height
== -1)
7700 /* w known, calculate h. */
7701 desired_height
= (double) desired_width
/ width
* height
;
7702 if (desired_width
== -1 && desired_height
!= -1)
7703 /* h known, calculate w. */
7704 desired_width
= (double) desired_height
/ height
* width
;
7705 if (desired_width
!= -1 && desired_height
!= -1)
7707 status
= MagickScaleImage (image_wand
, desired_width
, desired_height
);
7708 if (status
== MagickFalse
)
7710 image_error ("Imagemagick scale failed", Qnil
, Qnil
);
7711 imagemagick_error (image_wand
);
7712 goto imagemagick_error
;
7716 /* crop behaves similar to image slicing in Emacs but is more memory
7718 crop
= image_spec_value (img
->spec
, QCcrop
, NULL
);
7720 if (CONSP (crop
) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop
)))
7722 /* After some testing, it seems MagickCropImage is the fastest crop
7723 function in ImageMagick. This crop function seems to do less copying
7724 than the alternatives, but it still reads the entire image into memory
7725 before cropping, which is apparently difficult to avoid when using
7727 size_t crop_width
= XINT (XCAR (crop
));
7729 if (CONSP (crop
) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop
)))
7731 size_t crop_height
= XINT (XCAR (crop
));
7733 if (CONSP (crop
) && TYPE_RANGED_INTEGERP (ssize_t
, XCAR (crop
)))
7735 ssize_t crop_x
= XINT (XCAR (crop
));
7737 if (CONSP (crop
) && TYPE_RANGED_INTEGERP (ssize_t
, XCAR (crop
)))
7739 ssize_t crop_y
= XINT (XCAR (crop
));
7740 MagickCropImage (image_wand
, crop_width
, crop_height
,
7747 /* Furthermore :rotation. we need background color and angle for
7750 TODO background handling for rotation specified_bg =
7751 image_spec_value (img->spec, QCbackground, NULL); if (!STRINGP
7753 value
= image_spec_value (img
->spec
, QCrotation
, NULL
);
7756 rotation
= extract_float (value
);
7757 status
= MagickRotateImage (image_wand
, bg_wand
, rotation
);
7758 if (status
== MagickFalse
)
7760 image_error ("Imagemagick image rotate failed", Qnil
, Qnil
);
7761 imagemagick_error (image_wand
);
7762 goto imagemagick_error
;
7766 /* Finally we are done manipulating the image. Figure out the
7767 resulting width/height and transfer ownership to Emacs. */
7768 height
= MagickGetImageHeight (image_wand
);
7769 width
= MagickGetImageWidth (image_wand
);
7771 /* Set the canvas background color to the frame or specified
7772 background, and flatten the image. Note: as of ImageMagick
7773 6.6.0, SVG image transparency is not handled properly
7774 (e.g. etc/images/splash.svg shows a white background always). */
7776 MagickWand
*new_wand
;
7777 MagickSetImageBackgroundColor (image_wand
, bg_wand
);
7778 #ifdef HAVE_MAGICKMERGEIMAGELAYERS
7779 new_wand
= MagickMergeImageLayers (image_wand
, MergeLayer
);
7781 new_wand
= MagickFlattenImages (image_wand
);
7783 DestroyMagickWand (image_wand
);
7784 image_wand
= new_wand
;
7787 if (! (width
<= INT_MAX
&& height
<= INT_MAX
7788 && check_image_size (f
, width
, height
)))
7790 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7791 goto imagemagick_error
;
7794 /* We can now get a valid pixel buffer from the imagemagick file, if all
7797 init_color_table ();
7799 #ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
7800 if (imagemagick_render_type
!= 0)
7802 /* Magicexportimage is normally faster than pixelpushing. This
7803 method is also well tested. Some aspects of this method are
7804 ad-hoc and needs to be more researched. */
7805 int imagedepth
= 24; /*MagickGetImageDepth(image_wand);*/
7806 const char *exportdepth
= imagedepth
<= 8 ? "I" : "BGRP"; /*"RGBP";*/
7807 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7808 if (!x_create_x_image_and_pixmap (f
, width
, height
, imagedepth
,
7809 &ximg
, &img
->pixmap
))
7811 #ifdef COLOR_TABLE_SUPPORT
7812 free_color_table ();
7814 image_error ("Imagemagick X bitmap allocation failure", Qnil
, Qnil
);
7815 goto imagemagick_error
;
7818 /* Oddly, the below code doesn't seem to work:*/
7819 /* switch(ximg->bitmap_unit){ */
7821 /* pixelwidth=CharPixel; */
7824 /* pixelwidth=ShortPixel; */
7827 /* pixelwidth=LongPixel; */
7831 Here im just guessing the format of the bitmap.
7832 happens to work fine for:
7835 seems about 3 times as fast as pixel pushing(not carefully measured)
7837 pixelwidth
= CharPixel
; /*??? TODO figure out*/
7838 MagickExportImagePixels (image_wand
, 0, 0, width
, height
,
7839 exportdepth
, pixelwidth
, ximg
->data
);
7842 #endif /* HAVE_MAGICKEXPORTIMAGEPIXELS */
7844 size_t image_height
;
7846 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7847 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
7848 &ximg
, &img
->pixmap
))
7850 #ifdef COLOR_TABLE_SUPPORT
7851 free_color_table ();
7853 image_error ("Imagemagick X bitmap allocation failure", Qnil
, Qnil
);
7854 goto imagemagick_error
;
7857 /* Copy imagemagick image to x with primitive yet robust pixel
7858 pusher loop. This has been tested a lot with many different
7861 /* Copy pixels from the imagemagick image structure to the x image map. */
7862 iterator
= NewPixelIterator (image_wand
);
7863 if (iterator
== (PixelIterator
*) NULL
)
7865 #ifdef COLOR_TABLE_SUPPORT
7866 free_color_table ();
7868 x_destroy_x_image (ximg
);
7869 image_error ("Imagemagick pixel iterator creation failed",
7871 goto imagemagick_error
;
7874 image_height
= MagickGetImageHeight (image_wand
);
7875 for (y
= 0; y
< image_height
; y
++)
7877 pixels
= PixelGetNextIteratorRow (iterator
, &width
);
7878 if (pixels
== (PixelWand
**) NULL
)
7880 for (x
= 0; x
< (long) width
; x
++)
7882 PixelGetMagickColor (pixels
[x
], &pixel
);
7883 XPutPixel (ximg
, x
, y
,
7884 lookup_rgb_color (f
,
7890 DestroyPixelIterator (iterator
);
7893 #ifdef COLOR_TABLE_SUPPORT
7894 /* Remember colors allocated for this image. */
7895 img
->colors
= colors_in_color_table (&img
->ncolors
);
7896 free_color_table ();
7897 #endif /* COLOR_TABLE_SUPPORT */
7900 img
->height
= height
;
7902 /* Put the image into the pixmap, then free the X image and its
7904 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7905 x_destroy_x_image (ximg
);
7907 /* Final cleanup. image_wand should be the only resource left. */
7908 DestroyMagickWand (image_wand
);
7909 if (bg_wand
) DestroyPixelWand (bg_wand
);
7911 /* `MagickWandTerminus' terminates the imagemagick environment. */
7912 MagickWandTerminus ();
7917 DestroyMagickWand (image_wand
);
7918 if (bg_wand
) DestroyPixelWand (bg_wand
);
7920 MagickWandTerminus ();
7921 /* TODO more cleanup. */
7922 image_error ("Error parsing IMAGEMAGICK image `%s'", img
->spec
, Qnil
);
7927 /* Load IMAGEMAGICK image IMG for use on frame F. Value is non-zero if
7928 successful. this function will go into the imagemagick_type structure, and
7929 the prototype thus needs to be compatible with that structure. */
7932 imagemagick_load (struct frame
*f
, struct image
*img
)
7935 Lisp_Object file_name
;
7937 /* If IMG->spec specifies a file name, create a non-file spec from it. */
7938 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
7939 if (STRINGP (file_name
))
7943 file
= x_find_image_file (file_name
);
7944 if (!STRINGP (file
))
7946 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
7949 success_p
= imagemagick_load_image (f
, img
, 0, 0, SSDATA (file
));
7951 /* Else its not a file, its a lisp object. Load the image from a
7952 lisp object rather than a file. */
7957 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7958 if (!STRINGP (data
))
7960 image_error ("Invalid image data `%s'", data
, Qnil
);
7963 success_p
= imagemagick_load_image (f
, img
, SDATA (data
),
7964 SBYTES (data
), NULL
);
7970 DEFUN ("imagemagick-types", Fimagemagick_types
, Simagemagick_types
, 0, 0, 0,
7971 doc
: /* Return a list of image types supported by ImageMagick.
7972 Each entry in this list is a symbol named after an ImageMagick format
7973 tag. See the ImageMagick manual for a list of ImageMagick formats and
7974 their descriptions (http://www.imagemagick.org/script/formats.php).
7975 You can also try the shell command: `identify -list format'.
7977 Note that ImageMagick recognizes many file-types that Emacs does not
7978 recognize as images, such as C. See `imagemagick-types-enable'
7979 and `imagemagick-types-inhibit'. */)
7982 Lisp_Object typelist
= Qnil
;
7985 char **imtypes
= GetMagickList ("*", &numf
, &ex
);
7987 Lisp_Object Qimagemagicktype
;
7988 for (i
= 0; i
< numf
; i
++)
7990 Qimagemagicktype
= intern (imtypes
[i
]);
7991 typelist
= Fcons (Qimagemagicktype
, typelist
);
7993 return Fnreverse (typelist
);
7996 #endif /* defined (HAVE_IMAGEMAGICK) */
8000 /***********************************************************************
8002 ***********************************************************************/
8004 #if defined (HAVE_RSVG)
8006 /* Function prototypes. */
8008 static int svg_image_p (Lisp_Object object
);
8009 static int svg_load (struct frame
*f
, struct image
*img
);
8011 static int svg_load_image (struct frame
*, struct image
*,
8012 unsigned char *, ptrdiff_t);
8014 /* The symbol `svg' identifying images of this type. */
8016 static Lisp_Object Qsvg
;
8018 /* Indices of image specification fields in svg_format, below. */
8020 enum svg_keyword_index
8035 /* Vector of image_keyword structures describing the format
8036 of valid user-defined image specifications. */
8038 static const struct image_keyword svg_format
[SVG_LAST
] =
8040 {":type", IMAGE_SYMBOL_VALUE
, 1},
8041 {":data", IMAGE_STRING_VALUE
, 0},
8042 {":file", IMAGE_STRING_VALUE
, 0},
8043 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8044 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
8045 {":relief", IMAGE_INTEGER_VALUE
, 0},
8046 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8047 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8048 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8049 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8052 /* Structure describing the image type `svg'. Its the same type of
8053 structure defined for all image formats, handled by emacs image
8054 functions. See struct image_type in dispextern.h. */
8056 static struct image_type svg_type
=
8058 /* An identifier showing that this is an image structure for the SVG format. */
8060 /* Handle to a function that can be used to identify a SVG file. */
8062 /* Handle to function used to load a SVG file. */
8064 /* Handle to function to free sresources for SVG. */
8066 /* An internal field to link to the next image type in a list of
8067 image types, will be filled in when registering the format. */
8072 /* Return non-zero if OBJECT is a valid SVG image specification. Do
8073 this by calling parse_image_spec and supplying the keywords that
8074 identify the SVG format. */
8077 svg_image_p (Lisp_Object object
)
8079 struct image_keyword fmt
[SVG_LAST
];
8080 memcpy (fmt
, svg_format
, sizeof fmt
);
8082 if (!parse_image_spec (object
, fmt
, SVG_LAST
, Qsvg
))
8085 /* Must specify either the :data or :file keyword. */
8086 return fmt
[SVG_FILE
].count
+ fmt
[SVG_DATA
].count
== 1;
8089 #include <librsvg/rsvg.h>
8093 /* SVG library functions. */
8094 DEF_IMGLIB_FN (RsvgHandle
*, rsvg_handle_new
);
8095 DEF_IMGLIB_FN (void, rsvg_handle_get_dimensions
);
8096 DEF_IMGLIB_FN (gboolean
, rsvg_handle_write
);
8097 DEF_IMGLIB_FN (gboolean
, rsvg_handle_close
);
8098 DEF_IMGLIB_FN (GdkPixbuf
*, rsvg_handle_get_pixbuf
);
8100 DEF_IMGLIB_FN (int, gdk_pixbuf_get_width
);
8101 DEF_IMGLIB_FN (int, gdk_pixbuf_get_height
);
8102 DEF_IMGLIB_FN (guchar
*, gdk_pixbuf_get_pixels
);
8103 DEF_IMGLIB_FN (int, gdk_pixbuf_get_rowstride
);
8104 DEF_IMGLIB_FN (GdkColorspace
, gdk_pixbuf_get_colorspace
);
8105 DEF_IMGLIB_FN (int, gdk_pixbuf_get_n_channels
);
8106 DEF_IMGLIB_FN (gboolean
, gdk_pixbuf_get_has_alpha
);
8107 DEF_IMGLIB_FN (int, gdk_pixbuf_get_bits_per_sample
);
8109 DEF_IMGLIB_FN (void, g_type_init
);
8110 DEF_IMGLIB_FN (void, g_object_unref
);
8111 DEF_IMGLIB_FN (void, g_error_free
);
8113 Lisp_Object Qgdk_pixbuf
, Qglib
, Qgobject
;
8116 init_svg_functions (Lisp_Object libraries
)
8118 HMODULE library
, gdklib
, glib
, gobject
;
8120 if (!(glib
= w32_delayed_load (libraries
, Qglib
))
8121 || !(gobject
= w32_delayed_load (libraries
, Qgobject
))
8122 || !(gdklib
= w32_delayed_load (libraries
, Qgdk_pixbuf
))
8123 || !(library
= w32_delayed_load (libraries
, Qsvg
)))
8126 LOAD_IMGLIB_FN (library
, rsvg_handle_new
);
8127 LOAD_IMGLIB_FN (library
, rsvg_handle_get_dimensions
);
8128 LOAD_IMGLIB_FN (library
, rsvg_handle_write
);
8129 LOAD_IMGLIB_FN (library
, rsvg_handle_close
);
8130 LOAD_IMGLIB_FN (library
, rsvg_handle_get_pixbuf
);
8132 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_width
);
8133 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_height
);
8134 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_pixels
);
8135 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_rowstride
);
8136 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_colorspace
);
8137 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_n_channels
);
8138 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_has_alpha
);
8139 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_bits_per_sample
);
8141 LOAD_IMGLIB_FN (gobject
, g_type_init
);
8142 LOAD_IMGLIB_FN (gobject
, g_object_unref
);
8143 LOAD_IMGLIB_FN (glib
, g_error_free
);
8149 /* The following aliases for library functions allow dynamic loading
8150 to be used on some platforms. */
8151 #define fn_rsvg_handle_new rsvg_handle_new
8152 #define fn_rsvg_handle_get_dimensions rsvg_handle_get_dimensions
8153 #define fn_rsvg_handle_write rsvg_handle_write
8154 #define fn_rsvg_handle_close rsvg_handle_close
8155 #define fn_rsvg_handle_get_pixbuf rsvg_handle_get_pixbuf
8157 #define fn_gdk_pixbuf_get_width gdk_pixbuf_get_width
8158 #define fn_gdk_pixbuf_get_height gdk_pixbuf_get_height
8159 #define fn_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels
8160 #define fn_gdk_pixbuf_get_rowstride gdk_pixbuf_get_rowstride
8161 #define fn_gdk_pixbuf_get_colorspace gdk_pixbuf_get_colorspace
8162 #define fn_gdk_pixbuf_get_n_channels gdk_pixbuf_get_n_channels
8163 #define fn_gdk_pixbuf_get_has_alpha gdk_pixbuf_get_has_alpha
8164 #define fn_gdk_pixbuf_get_bits_per_sample gdk_pixbuf_get_bits_per_sample
8166 #define fn_g_type_init g_type_init
8167 #define fn_g_object_unref g_object_unref
8168 #define fn_g_error_free g_error_free
8169 #endif /* !HAVE_NTGUI */
8171 /* Load SVG image IMG for use on frame F. Value is non-zero if
8172 successful. this function will go into the svg_type structure, and
8173 the prototype thus needs to be compatible with that structure. */
8176 svg_load (struct frame
*f
, struct image
*img
)
8179 Lisp_Object file_name
;
8181 /* If IMG->spec specifies a file name, create a non-file spec from it. */
8182 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
8183 if (STRINGP (file_name
))
8186 unsigned char *contents
;
8189 file
= x_find_image_file (file_name
);
8190 if (!STRINGP (file
))
8192 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
8196 /* Read the entire file into memory. */
8197 contents
= slurp_file (SSDATA (file
), &size
);
8198 if (contents
== NULL
)
8200 image_error ("Error loading SVG image `%s'", img
->spec
, Qnil
);
8203 /* If the file was slurped into memory properly, parse it. */
8204 success_p
= svg_load_image (f
, img
, contents
, size
);
8207 /* Else its not a file, its a lisp object. Load the image from a
8208 lisp object rather than a file. */
8213 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8214 if (!STRINGP (data
))
8216 image_error ("Invalid image data `%s'", data
, Qnil
);
8219 success_p
= svg_load_image (f
, img
, SDATA (data
), SBYTES (data
));
8225 /* svg_load_image is a helper function for svg_load, which does the
8226 actual loading given contents and size, apart from frame and image
8227 structures, passed from svg_load.
8229 Uses librsvg to do most of the image processing.
8231 Returns non-zero when successful. */
8233 svg_load_image (struct frame
*f
, /* Pointer to emacs frame structure. */
8234 struct image
*img
, /* Pointer to emacs image structure. */
8235 unsigned char *contents
, /* String containing the SVG XML data to be parsed. */
8236 ptrdiff_t size
) /* Size of data in bytes. */
8238 RsvgHandle
*rsvg_handle
;
8239 RsvgDimensionData dimension_data
;
8244 const guint8
*pixels
;
8247 Lisp_Object specified_bg
;
8252 /* g_type_init is a glib function that must be called prior to using
8253 gnome type library functions. */
8255 /* Make a handle to a new rsvg object. */
8256 rsvg_handle
= fn_rsvg_handle_new ();
8258 /* Parse the contents argument and fill in the rsvg_handle. */
8259 fn_rsvg_handle_write (rsvg_handle
, contents
, size
, &err
);
8260 if (err
) goto rsvg_error
;
8262 /* The parsing is complete, rsvg_handle is ready to used, close it
8263 for further writes. */
8264 fn_rsvg_handle_close (rsvg_handle
, &err
);
8265 if (err
) goto rsvg_error
;
8267 fn_rsvg_handle_get_dimensions (rsvg_handle
, &dimension_data
);
8268 if (! check_image_size (f
, dimension_data
.width
, dimension_data
.height
))
8270 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
8274 /* We can now get a valid pixel buffer from the svg file, if all
8276 pixbuf
= fn_rsvg_handle_get_pixbuf (rsvg_handle
);
8277 if (!pixbuf
) goto rsvg_error
;
8278 fn_g_object_unref (rsvg_handle
);
8280 /* Extract some meta data from the svg handle. */
8281 width
= fn_gdk_pixbuf_get_width (pixbuf
);
8282 height
= fn_gdk_pixbuf_get_height (pixbuf
);
8283 pixels
= fn_gdk_pixbuf_get_pixels (pixbuf
);
8284 rowstride
= fn_gdk_pixbuf_get_rowstride (pixbuf
);
8286 /* Validate the svg meta data. */
8287 eassert (fn_gdk_pixbuf_get_colorspace (pixbuf
) == GDK_COLORSPACE_RGB
);
8288 eassert (fn_gdk_pixbuf_get_n_channels (pixbuf
) == 4);
8289 eassert (fn_gdk_pixbuf_get_has_alpha (pixbuf
));
8290 eassert (fn_gdk_pixbuf_get_bits_per_sample (pixbuf
) == 8);
8292 /* Try to create a x pixmap to hold the svg pixmap. */
8293 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8295 fn_g_object_unref (pixbuf
);
8299 init_color_table ();
8301 /* Handle alpha channel by combining the image with a background
8303 specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
8304 if (!STRINGP (specified_bg
)
8305 || !x_defined_color (f
, SSDATA (specified_bg
), &background
, 0))
8308 background
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
8309 x_query_color (f
, &background
);
8311 ns_query_color (FRAME_BACKGROUND_COLOR (f
), &background
, 1);
8315 /* SVG pixmaps specify transparency in the last byte, so right
8316 shift 8 bits to get rid of it, since emacs doesn't support
8318 background
.red
>>= 8;
8319 background
.green
>>= 8;
8320 background
.blue
>>= 8;
8322 /* This loop handles opacity values, since Emacs assumes
8323 non-transparent images. Each pixel must be "flattened" by
8324 calculating the resulting color, given the transparency of the
8325 pixel, and the image background color. */
8326 for (y
= 0; y
< height
; ++y
)
8328 for (x
= 0; x
< width
; ++x
)
8338 opacity
= *pixels
++;
8340 red
= ((red
* opacity
)
8341 + (background
.red
* ((1 << 8) - opacity
)));
8342 green
= ((green
* opacity
)
8343 + (background
.green
* ((1 << 8) - opacity
)));
8344 blue
= ((blue
* opacity
)
8345 + (background
.blue
* ((1 << 8) - opacity
)));
8347 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, red
, green
, blue
));
8350 pixels
+= rowstride
- 4 * width
;
8353 #ifdef COLOR_TABLE_SUPPORT
8354 /* Remember colors allocated for this image. */
8355 img
->colors
= colors_in_color_table (&img
->ncolors
);
8356 free_color_table ();
8357 #endif /* COLOR_TABLE_SUPPORT */
8359 fn_g_object_unref (pixbuf
);
8362 img
->height
= height
;
8364 /* Maybe fill in the background field while we have ximg handy.
8365 Casting avoids a GCC warning. */
8366 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
8368 /* Put the image into the pixmap, then free the X image and its
8370 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8371 x_destroy_x_image (ximg
);
8376 fn_g_object_unref (rsvg_handle
);
8377 /* FIXME: Use error->message so the user knows what is the actual
8378 problem with the image. */
8379 image_error ("Error parsing SVG image `%s'", img
->spec
, Qnil
);
8380 fn_g_error_free (err
);
8384 #endif /* defined (HAVE_RSVG) */
8389 /***********************************************************************
8391 ***********************************************************************/
8393 #ifdef HAVE_X_WINDOWS
8394 #define HAVE_GHOSTSCRIPT 1
8395 #endif /* HAVE_X_WINDOWS */
8397 #ifdef HAVE_GHOSTSCRIPT
8399 static int gs_image_p (Lisp_Object object
);
8400 static int gs_load (struct frame
*f
, struct image
*img
);
8401 static void gs_clear_image (struct frame
*f
, struct image
*img
);
8403 /* Keyword symbols. */
8405 static Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
8407 /* Indices of image specification fields in gs_format, below. */
8409 enum gs_keyword_index
8427 /* Vector of image_keyword structures describing the format
8428 of valid user-defined image specifications. */
8430 static const struct image_keyword gs_format
[GS_LAST
] =
8432 {":type", IMAGE_SYMBOL_VALUE
, 1},
8433 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8434 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8435 {":file", IMAGE_STRING_VALUE
, 1},
8436 {":loader", IMAGE_FUNCTION_VALUE
, 0},
8437 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
8438 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8439 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
8440 {":relief", IMAGE_INTEGER_VALUE
, 0},
8441 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8442 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8443 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8444 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8447 /* Structure describing the image type `ghostscript'. */
8449 static struct image_type gs_type
=
8459 /* Free X resources of Ghostscript image IMG which is used on frame F. */
8462 gs_clear_image (struct frame
*f
, struct image
*img
)
8464 x_clear_image (f
, img
);
8468 /* Return non-zero if OBJECT is a valid Ghostscript image
8472 gs_image_p (Lisp_Object object
)
8474 struct image_keyword fmt
[GS_LAST
];
8478 memcpy (fmt
, gs_format
, sizeof fmt
);
8480 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
8483 /* Bounding box must be a list or vector containing 4 integers. */
8484 tem
= fmt
[GS_BOUNDING_BOX
].value
;
8487 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
8488 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
8493 else if (VECTORP (tem
))
8495 if (ASIZE (tem
) != 4)
8497 for (i
= 0; i
< 4; ++i
)
8498 if (!INTEGERP (AREF (tem
, i
)))
8508 /* Load Ghostscript image IMG for use on frame F. Value is non-zero
8512 gs_load (struct frame
*f
, struct image
*img
)
8514 uprintmax_t printnum1
, printnum2
;
8515 char buffer
[sizeof " " + INT_STRLEN_BOUND (printmax_t
)];
8516 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
8518 double in_width
, in_height
;
8519 Lisp_Object pixel_colors
= Qnil
;
8521 /* Compute pixel size of pixmap needed from the given size in the
8522 image specification. Sizes in the specification are in pt. 1 pt
8523 = 1/72 in, xdpi and ydpi are stored in the frame's X display
8525 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
8526 in_width
= INTEGERP (pt_width
) ? XFASTINT (pt_width
) / 72.0 : 0;
8527 in_width
*= FRAME_X_DISPLAY_INFO (f
)->resx
;
8528 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
8529 in_height
= INTEGERP (pt_height
) ? XFASTINT (pt_height
) / 72.0 : 0;
8530 in_height
*= FRAME_X_DISPLAY_INFO (f
)->resy
;
8532 if (! (in_width
<= INT_MAX
&& in_height
<= INT_MAX
8533 && check_image_size (f
, in_width
, in_height
)))
8535 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
8538 img
->width
= in_width
;
8539 img
->height
= in_height
;
8541 /* Create the pixmap. */
8542 eassert (img
->pixmap
== NO_PIXMAP
);
8544 if (x_check_image_size (0, img
->width
, img
->height
))
8546 /* Only W32 version did BLOCK_INPUT here. ++kfs */
8548 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8549 img
->width
, img
->height
,
8550 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
8556 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
8560 /* Call the loader to fill the pixmap. It returns a process object
8561 if successful. We do not record_unwind_protect here because
8562 other places in redisplay like calling window scroll functions
8563 don't either. Let the Lisp loader use `unwind-protect' instead. */
8564 printnum1
= FRAME_X_WINDOW (f
);
8565 printnum2
= img
->pixmap
;
8566 sprintf (buffer
, "%"pMu
" %"pMu
, printnum1
, printnum2
);
8567 window_and_pixmap_id
= build_string (buffer
);
8569 printnum1
= FRAME_FOREGROUND_PIXEL (f
);
8570 printnum2
= FRAME_BACKGROUND_PIXEL (f
);
8571 sprintf (buffer
, "%"pMu
" %"pMu
, printnum1
, printnum2
);
8572 pixel_colors
= build_string (buffer
);
8574 XSETFRAME (frame
, f
);
8575 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
8577 loader
= intern ("gs-load-image");
8579 img
->lisp_data
= call6 (loader
, frame
, img
->spec
,
8580 make_number (img
->width
),
8581 make_number (img
->height
),
8582 window_and_pixmap_id
,
8584 return PROCESSP (img
->lisp_data
);
8588 /* Kill the Ghostscript process that was started to fill PIXMAP on
8589 frame F. Called from XTread_socket when receiving an event
8590 telling Emacs that Ghostscript has finished drawing. */
8593 x_kill_gs_process (Pixmap pixmap
, struct frame
*f
)
8595 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
8600 /* Find the image containing PIXMAP. */
8601 for (i
= 0; i
< c
->used
; ++i
)
8602 if (c
->images
[i
]->pixmap
== pixmap
)
8605 /* Should someone in between have cleared the image cache, for
8606 instance, give up. */
8610 /* Kill the GS process. We should have found PIXMAP in the image
8611 cache and its image should contain a process object. */
8613 eassert (PROCESSP (img
->lisp_data
));
8614 Fkill_process (img
->lisp_data
, Qnil
);
8615 img
->lisp_data
= Qnil
;
8617 #if defined (HAVE_X_WINDOWS)
8619 /* On displays with a mutable colormap, figure out the colors
8620 allocated for the image by looking at the pixels of an XImage for
8622 class = FRAME_X_VISUAL (f
)->class;
8623 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
8629 /* Try to get an XImage for img->pixmep. */
8630 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
8631 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
8636 /* Initialize the color table. */
8637 init_color_table ();
8639 /* For each pixel of the image, look its color up in the
8640 color table. After having done so, the color table will
8641 contain an entry for each color used by the image. */
8642 for (y
= 0; y
< img
->height
; ++y
)
8643 for (x
= 0; x
< img
->width
; ++x
)
8645 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
8646 lookup_pixel_color (f
, pixel
);
8649 /* Record colors in the image. Free color table and XImage. */
8650 #ifdef COLOR_TABLE_SUPPORT
8651 img
->colors
= colors_in_color_table (&img
->ncolors
);
8652 free_color_table ();
8654 XDestroyImage (ximg
);
8656 #if 0 /* This doesn't seem to be the case. If we free the colors
8657 here, we get a BadAccess later in x_clear_image when
8658 freeing the colors. */
8659 /* We have allocated colors once, but Ghostscript has also
8660 allocated colors on behalf of us. So, to get the
8661 reference counts right, free them once. */
8663 x_free_colors (f
, img
->colors
, img
->ncolors
);
8667 image_error ("Cannot get X image of `%s'; colors will not be freed",
8672 #endif /* HAVE_X_WINDOWS */
8674 /* Now that we have the pixmap, compute mask and transform the
8675 image if requested. */
8677 postprocess_image (f
, img
);
8681 #endif /* HAVE_GHOSTSCRIPT */
8684 /***********************************************************************
8686 ***********************************************************************/
8690 DEFUN ("imagep", Fimagep
, Simagep
, 1, 1, 0,
8691 doc
: /* Value is non-nil if SPEC is a valid image specification. */)
8694 return valid_image_p (spec
) ? Qt
: Qnil
;
8698 DEFUN ("lookup-image", Flookup_image
, Slookup_image
, 1, 1, 0, "")
8703 if (valid_image_p (spec
))
8704 id
= lookup_image (SELECTED_FRAME (), spec
);
8707 return make_number (id
);
8710 #endif /* GLYPH_DEBUG */
8713 /***********************************************************************
8715 ***********************************************************************/
8718 /* Image types that rely on external libraries are loaded dynamically
8719 if the library is available. */
8720 #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8721 define_image_type (image_type, init_lib_fn (libraries))
8723 #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
8724 define_image_type (image_type, 1)
8725 #endif /* HAVE_NTGUI */
8727 DEFUN ("init-image-library", Finit_image_library
, Sinit_image_library
, 2, 2, 0,
8728 doc
: /* Initialize image library implementing image type TYPE.
8729 Return non-nil if TYPE is a supported image type.
8731 Image types pbm and xbm are prebuilt; other types are loaded here.
8732 Libraries to load are specified in alist LIBRARIES (usually, the value
8733 of `dynamic-library-alist', which see). */)
8734 (Lisp_Object type
, Lisp_Object libraries
)
8737 /* Don't try to reload the library. */
8738 Lisp_Object tested
= Fassq (type
, Vlibrary_cache
);
8740 return XCDR (tested
);
8743 /* Types pbm and xbm are built-in and always available. */
8744 if (EQ (type
, Qpbm
) || EQ (type
, Qxbm
))
8747 #if defined (HAVE_XPM) || defined (HAVE_NS)
8748 if (EQ (type
, Qxpm
))
8749 return CHECK_LIB_AVAILABLE (&xpm_type
, init_xpm_functions
, libraries
);
8752 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8753 if (EQ (type
, Qjpeg
))
8754 return CHECK_LIB_AVAILABLE (&jpeg_type
, init_jpeg_functions
, libraries
);
8757 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8758 if (EQ (type
, Qtiff
))
8759 return CHECK_LIB_AVAILABLE (&tiff_type
, init_tiff_functions
, libraries
);
8762 #if defined (HAVE_GIF) || defined (HAVE_NS)
8763 if (EQ (type
, Qgif
))
8764 return CHECK_LIB_AVAILABLE (&gif_type
, init_gif_functions
, libraries
);
8767 #if defined (HAVE_PNG) || defined (HAVE_NS)
8768 if (EQ (type
, Qpng
))
8769 return CHECK_LIB_AVAILABLE (&png_type
, init_png_functions
, libraries
);
8772 #if defined (HAVE_RSVG)
8773 if (EQ (type
, Qsvg
))
8774 return CHECK_LIB_AVAILABLE (&svg_type
, init_svg_functions
, libraries
);
8777 #if defined (HAVE_IMAGEMAGICK)
8778 if (EQ (type
, Qimagemagick
))
8779 return CHECK_LIB_AVAILABLE (&imagemagick_type
, init_imagemagick_functions
,
8783 #ifdef HAVE_GHOSTSCRIPT
8784 if (EQ (type
, Qpostscript
))
8785 return CHECK_LIB_AVAILABLE (&gs_type
, init_gs_functions
, libraries
);
8788 /* If the type is not recognized, avoid testing it ever again. */
8789 CACHE_IMAGE_TYPE (type
, Qnil
);
8794 syms_of_image (void)
8796 /* Initialize this only once, since that's what we do with Vimage_types
8797 and they are supposed to be in sync. Initializing here gives correct
8798 operation on GNU/Linux of calling dump-emacs after loading some images. */
8801 /* Must be defined now because we're going to update it below, while
8802 defining the supported image types. */
8803 DEFVAR_LISP ("image-types", Vimage_types
,
8804 doc
: /* List of potentially supported image types.
8805 Each element of the list is a symbol for an image type, like 'jpeg or 'png.
8806 To check whether it is really supported, use `image-type-available-p'. */);
8807 Vimage_types
= Qnil
;
8809 DEFVAR_LISP ("max-image-size", Vmax_image_size
,
8810 doc
: /* Maximum size of images.
8811 Emacs will not load an image into memory if its pixel width or
8812 pixel height exceeds this limit.
8814 If the value is an integer, it directly specifies the maximum
8815 image height and width, measured in pixels. If it is a floating
8816 point number, it specifies the maximum image height and width
8817 as a ratio to the frame height and width. If the value is
8818 non-numeric, there is no explicit limit on the size of images. */);
8819 Vmax_image_size
= make_float (MAX_IMAGE_SIZE
);
8821 DEFSYM (Qpbm
, "pbm");
8822 ADD_IMAGE_TYPE (Qpbm
);
8824 DEFSYM (Qxbm
, "xbm");
8825 ADD_IMAGE_TYPE (Qxbm
);
8827 define_image_type (&xbm_type
, 1);
8828 define_image_type (&pbm_type
, 1);
8830 DEFSYM (Qcount
, "count");
8831 DEFSYM (Qextension_data
, "extension-data");
8832 DEFSYM (Qdelay
, "delay");
8834 DEFSYM (QCascent
, ":ascent");
8835 DEFSYM (QCmargin
, ":margin");
8836 DEFSYM (QCrelief
, ":relief");
8837 DEFSYM (QCconversion
, ":conversion");
8838 DEFSYM (QCcolor_symbols
, ":color-symbols");
8839 DEFSYM (QCheuristic_mask
, ":heuristic-mask");
8840 DEFSYM (QCindex
, ":index");
8841 DEFSYM (QCgeometry
, ":geometry");
8842 DEFSYM (QCcrop
, ":crop");
8843 DEFSYM (QCrotation
, ":rotation");
8844 DEFSYM (QCmatrix
, ":matrix");
8845 DEFSYM (QCcolor_adjustment
, ":color-adjustment");
8846 DEFSYM (QCmask
, ":mask");
8848 DEFSYM (Qlaplace
, "laplace");
8849 DEFSYM (Qemboss
, "emboss");
8850 DEFSYM (Qedge_detection
, "edge-detection");
8851 DEFSYM (Qheuristic
, "heuristic");
8853 DEFSYM (Qpostscript
, "postscript");
8854 #ifdef HAVE_GHOSTSCRIPT
8855 ADD_IMAGE_TYPE (Qpostscript
);
8856 DEFSYM (QCloader
, ":loader");
8857 DEFSYM (QCbounding_box
, ":bounding-box");
8858 DEFSYM (QCpt_width
, ":pt-width");
8859 DEFSYM (QCpt_height
, ":pt-height");
8860 #endif /* HAVE_GHOSTSCRIPT */
8863 DEFSYM (Qlibpng_version
, "libpng-version");
8864 Fset (Qlibpng_version
,
8866 make_number (PNG_LIBPNG_VER
)
8873 #if defined (HAVE_XPM) || defined (HAVE_NS)
8874 DEFSYM (Qxpm
, "xpm");
8875 ADD_IMAGE_TYPE (Qxpm
);
8878 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8879 DEFSYM (Qjpeg
, "jpeg");
8880 ADD_IMAGE_TYPE (Qjpeg
);
8883 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8884 DEFSYM (Qtiff
, "tiff");
8885 ADD_IMAGE_TYPE (Qtiff
);
8888 #if defined (HAVE_GIF) || defined (HAVE_NS)
8889 DEFSYM (Qgif
, "gif");
8890 ADD_IMAGE_TYPE (Qgif
);
8893 #if defined (HAVE_PNG) || defined (HAVE_NS)
8894 DEFSYM (Qpng
, "png");
8895 ADD_IMAGE_TYPE (Qpng
);
8898 #if defined (HAVE_IMAGEMAGICK)
8899 DEFSYM (Qimagemagick
, "imagemagick");
8900 ADD_IMAGE_TYPE (Qimagemagick
);
8903 #if defined (HAVE_RSVG)
8904 DEFSYM (Qsvg
, "svg");
8905 ADD_IMAGE_TYPE (Qsvg
);
8907 /* Other libraries used directly by svg code. */
8908 DEFSYM (Qgdk_pixbuf
, "gdk-pixbuf");
8909 DEFSYM (Qglib
, "glib");
8910 DEFSYM (Qgobject
, "gobject");
8911 #endif /* HAVE_NTGUI */
8912 #endif /* HAVE_RSVG */
8914 defsubr (&Sinit_image_library
);
8915 #ifdef HAVE_IMAGEMAGICK
8916 defsubr (&Simagemagick_types
);
8918 defsubr (&Sclear_image_cache
);
8919 defsubr (&Simage_flush
);
8920 defsubr (&Simage_size
);
8921 defsubr (&Simage_mask_p
);
8922 defsubr (&Simage_metadata
);
8926 defsubr (&Slookup_image
);
8929 DEFVAR_BOOL ("cross-disabled-images", cross_disabled_images
,
8930 doc
: /* Non-nil means always draw a cross over disabled images.
8931 Disabled images are those having a `:conversion disabled' property.
8932 A cross is always drawn on black & white displays. */);
8933 cross_disabled_images
= 0;
8935 DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path
,
8936 doc
: /* List of directories to search for window system bitmap files. */);
8937 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
8939 DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay
,
8940 doc
: /* Maximum time after which images are removed from the cache.
8941 When an image has not been displayed this many seconds, Emacs
8942 automatically removes it from the image cache. If the cache contains
8943 a large number of images, the actual eviction time may be shorter.
8944 The value can also be nil, meaning the cache is never cleared.
8946 The function `clear-image-cache' disregards this variable. */);
8947 Vimage_cache_eviction_delay
= make_number (300);
8948 #ifdef HAVE_IMAGEMAGICK
8949 DEFVAR_INT ("imagemagick-render-type", imagemagick_render_type
,
8950 doc
: /* Integer indicating which ImageMagick rendering method to use.
8952 0 -- the default method (pixel pushing)
8953 1 -- a newer method ("MagickExportImagePixels") that may perform
8954 better (speed etc) in some cases, but has not been as thoroughly
8955 tested with Emacs as the default method. This method requires
8956 ImageMagick version 6.4.6 (approximately) or later.
8958 /* MagickExportImagePixels is in 6.4.6-9, but not 6.4.4-10. */
8959 imagemagick_render_type
= 0;