1 /* Functions for image support on window system.
3 Copyright (C) 1989, 1992-2013 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/>. */
25 #if defined HAVE_LIBPNG_PNG_H
26 # 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"
52 #ifdef HAVE_SYS_STAT_H
54 #endif /* HAVE_SYS_STAT_H */
56 #ifdef HAVE_SYS_TYPES_H
57 #include <sys/types.h>
58 #endif /* HAVE_SYS_TYPES_H */
60 #ifdef HAVE_WINDOW_SYSTEM
62 #endif /* HAVE_WINDOW_SYSTEM */
65 #define COLOR_TABLE_SUPPORT 1
67 typedef struct x_bitmap_record Bitmap_Record
;
68 #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
69 #define NO_PIXMAP None
71 #define PIX_MASK_RETAIN 0
72 #define PIX_MASK_DRAW 1
73 #endif /* HAVE_X_WINDOWS */
77 /* We need (or want) w32.h only when we're _not_ compiling for Cygwin. */
82 /* W32_TODO : Color tables on W32. */
83 #undef COLOR_TABLE_SUPPORT
85 typedef struct w32_bitmap_record Bitmap_Record
;
86 #define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y)
89 #define PIX_MASK_RETAIN 0
90 #define PIX_MASK_DRAW 1
92 #define x_defined_color w32_defined_color
93 #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
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 */
102 #undef COLOR_TABLE_SUPPORT
104 typedef struct ns_bitmap_record Bitmap_Record
;
106 #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
111 #define PIX_MASK_RETAIN 0
112 #define PIX_MASK_DRAW 1
114 #define x_defined_color(f, name, color_def, alloc) \
115 ns_defined_color (f, name, color_def, alloc, 0)
116 #define DefaultDepthOfScreen(screen) x_display_list->n_planes
120 /* The symbol `postscript' identifying images of this type. */
122 static Lisp_Object Qpostscript
;
124 static void x_disable_image (struct frame
*, struct image
*);
125 static void x_edge_detection (struct frame
*, struct image
*, Lisp_Object
,
128 static void init_color_table (void);
129 static unsigned long lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
);
130 #ifdef COLOR_TABLE_SUPPORT
131 static void free_color_table (void);
132 static unsigned long *colors_in_color_table (int *n
);
135 Lisp_Object QCmax_width
, QCmax_height
;
137 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
138 id, which is just an int that this section returns. Bitmaps are
139 reference counted so they can be shared among frames.
141 Bitmap indices are guaranteed to be > 0, so a negative number can
142 be used to indicate no bitmap.
144 If you use x_create_bitmap_from_data, then you must keep track of
145 the bitmaps yourself. That is, creating a bitmap from the same
146 data more than once will not be caught. */
150 XGetImage (Display
*display
, Pixmap pixmap
, int x
, int y
,
151 unsigned int width
, unsigned int height
,
152 unsigned long plane_mask
, int format
)
154 /* TODO: not sure what this function is supposed to do.. */
155 ns_retain_object (pixmap
);
159 /* Use with images created by ns_image_for_XPM. */
161 XGetPixel (XImagePtr ximage
, int x
, int y
)
163 return ns_get_pixel (ximage
, x
, y
);
166 /* Use with images created by ns_image_for_XPM; alpha set to 1;
167 pixel is assumed to be in RGB form. */
169 XPutPixel (XImagePtr ximage
, int x
, int y
, unsigned long pixel
)
171 ns_put_pixel (ximage
, x
, y
, pixel
);
176 /* Functions to access the contents of a bitmap, given an id. */
179 x_bitmap_height (FRAME_PTR f
, ptrdiff_t id
)
181 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
185 x_bitmap_width (FRAME_PTR f
, ptrdiff_t id
)
187 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
190 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
192 x_bitmap_pixmap (FRAME_PTR f
, ptrdiff_t id
)
194 /* HAVE_NTGUI needs the explicit cast here. */
195 return (ptrdiff_t) FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
199 #ifdef HAVE_X_WINDOWS
201 x_bitmap_mask (FRAME_PTR f
, ptrdiff_t id
)
203 return FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].mask
;
207 /* Allocate a new bitmap record. Returns index of new record. */
210 x_allocate_bitmap_record (FRAME_PTR f
)
212 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
215 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
216 return ++dpyinfo
->bitmaps_last
;
218 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
219 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
223 xpalloc (dpyinfo
->bitmaps
, &dpyinfo
->bitmaps_size
,
224 10, -1, sizeof *dpyinfo
->bitmaps
);
225 return ++dpyinfo
->bitmaps_last
;
228 /* Add one reference to the reference count of the bitmap with id ID. */
231 x_reference_bitmap (FRAME_PTR f
, ptrdiff_t id
)
233 ++FRAME_X_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
236 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
239 x_create_bitmap_from_data (struct frame
*f
, char *bits
, unsigned int width
, unsigned int height
)
241 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
244 #ifdef HAVE_X_WINDOWS
246 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
247 bits
, width
, height
);
250 #endif /* HAVE_X_WINDOWS */
254 bitmap
= CreateBitmap (width
, height
,
255 FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_planes
,
256 FRAME_X_DISPLAY_INFO (XFRAME (frame
))->n_cbits
,
260 #endif /* HAVE_NTGUI */
263 void *bitmap
= ns_image_from_XBM (bits
, width
, height
);
268 id
= x_allocate_bitmap_record (f
);
271 dpyinfo
->bitmaps
[id
- 1].img
= bitmap
;
272 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
275 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
276 dpyinfo
->bitmaps
[id
- 1].height
= height
;
277 dpyinfo
->bitmaps
[id
- 1].width
= width
;
278 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
280 #ifdef HAVE_X_WINDOWS
281 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
282 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
283 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
284 #endif /* HAVE_X_WINDOWS */
287 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
288 dpyinfo
->bitmaps
[id
- 1].hinst
= NULL
;
289 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
290 #endif /* HAVE_NTGUI */
295 /* Create bitmap from file FILE for frame F. */
298 x_create_bitmap_from_file (struct frame
*f
, Lisp_Object file
)
300 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
303 return -1; /* W32_TODO : bitmap support */
304 #endif /* HAVE_NTGUI */
308 void *bitmap
= ns_image_from_file (file
);
314 id
= x_allocate_bitmap_record (f
);
315 dpyinfo
->bitmaps
[id
- 1].img
= bitmap
;
316 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
317 dpyinfo
->bitmaps
[id
- 1].file
= xmalloc (SBYTES (file
) + 1);
318 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
319 dpyinfo
->bitmaps
[id
- 1].height
= ns_image_width (bitmap
);
320 dpyinfo
->bitmaps
[id
- 1].width
= ns_image_height (bitmap
);
321 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SSDATA (file
));
325 #ifdef HAVE_X_WINDOWS
326 unsigned int width
, height
;
328 int xhot
, yhot
, result
;
334 /* Look for an existing bitmap with the same name. */
335 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
337 if (dpyinfo
->bitmaps
[id
].refcount
338 && dpyinfo
->bitmaps
[id
].file
339 && !strcmp (dpyinfo
->bitmaps
[id
].file
, SSDATA (file
)))
341 ++dpyinfo
->bitmaps
[id
].refcount
;
346 /* Search bitmap-file-path for the file, if appropriate. */
347 fd
= openp (Vx_bitmap_file_path
, file
, Qnil
, &found
, Qnil
);
352 filename
= SSDATA (found
);
354 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
355 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
356 if (result
!= BitmapSuccess
)
359 id
= x_allocate_bitmap_record (f
);
360 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
361 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
362 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
363 dpyinfo
->bitmaps
[id
- 1].file
= xmalloc (SBYTES (file
) + 1);
364 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
365 dpyinfo
->bitmaps
[id
- 1].height
= height
;
366 dpyinfo
->bitmaps
[id
- 1].width
= width
;
367 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, SSDATA (file
));
370 #endif /* HAVE_X_WINDOWS */
376 free_bitmap_record (Display_Info
*dpyinfo
, Bitmap_Record
*bm
)
378 #ifdef HAVE_X_WINDOWS
379 XFreePixmap (dpyinfo
->display
, bm
->pixmap
);
381 XFreePixmap (dpyinfo
->display
, bm
->mask
);
382 #endif /* HAVE_X_WINDOWS */
385 DeleteObject (bm
->pixmap
);
386 #endif /* HAVE_NTGUI */
389 ns_release_object (bm
->img
);
399 /* Remove reference to bitmap with id number ID. */
402 x_destroy_bitmap (FRAME_PTR f
, ptrdiff_t id
)
404 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
408 Bitmap_Record
*bm
= &dpyinfo
->bitmaps
[id
- 1];
410 if (--bm
->refcount
== 0)
413 free_bitmap_record (dpyinfo
, bm
);
419 /* Free all the bitmaps for the display specified by DPYINFO. */
422 x_destroy_all_bitmaps (Display_Info
*dpyinfo
)
425 Bitmap_Record
*bm
= dpyinfo
->bitmaps
;
427 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++, bm
++)
428 if (bm
->refcount
> 0)
429 free_bitmap_record (dpyinfo
, bm
);
431 dpyinfo
->bitmaps_last
= 0;
434 static bool x_create_x_image_and_pixmap (struct frame
*, int, int, int,
435 XImagePtr
*, Pixmap
*);
436 static void x_destroy_x_image (XImagePtr ximg
);
438 #ifdef HAVE_X_WINDOWS
440 /* Useful functions defined in the section
441 `Image type independent image structures' below. */
443 static unsigned long four_corners_best (XImagePtr ximg
,
446 unsigned long height
);
449 /* Create a mask of a bitmap. Note is this not a perfect mask.
450 It's nicer with some borders in this context */
453 x_create_bitmap_mask (struct frame
*f
, ptrdiff_t id
)
456 XImagePtr ximg
, mask_img
;
457 unsigned long width
, height
;
460 unsigned long x
, y
, xp
, xm
, yp
, ym
;
463 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
468 pixmap
= x_bitmap_pixmap (f
, id
);
469 width
= x_bitmap_width (f
, id
);
470 height
= x_bitmap_height (f
, id
);
473 ximg
= XGetImage (FRAME_X_DISPLAY (f
), pixmap
, 0, 0, width
, height
,
482 result
= x_create_x_image_and_pixmap (f
, width
, height
, 1, &mask_img
, &mask
);
487 XDestroyImage (ximg
);
491 bg
= four_corners_best (ximg
, NULL
, width
, height
);
493 for (y
= 0; y
< ximg
->height
; ++y
)
495 for (x
= 0; x
< ximg
->width
; ++x
)
497 xp
= x
!= ximg
->width
- 1 ? x
+ 1 : 0;
498 xm
= x
!= 0 ? x
- 1 : ximg
->width
- 1;
499 yp
= y
!= ximg
->height
- 1 ? y
+ 1 : 0;
500 ym
= y
!= 0 ? y
- 1 : ximg
->height
- 1;
501 if (XGetPixel (ximg
, x
, y
) == bg
502 && XGetPixel (ximg
, x
, yp
) == bg
503 && XGetPixel (ximg
, x
, ym
) == bg
504 && XGetPixel (ximg
, xp
, y
) == bg
505 && XGetPixel (ximg
, xp
, yp
) == bg
506 && XGetPixel (ximg
, xp
, ym
) == bg
507 && XGetPixel (ximg
, xm
, y
) == bg
508 && XGetPixel (ximg
, xm
, yp
) == bg
509 && XGetPixel (ximg
, xm
, ym
) == bg
)
510 XPutPixel (mask_img
, x
, y
, 0);
512 XPutPixel (mask_img
, x
, y
, 1);
516 eassert (input_blocked_p ());
517 gc
= XCreateGC (FRAME_X_DISPLAY (f
), mask
, 0, NULL
);
518 XPutImage (FRAME_X_DISPLAY (f
), mask
, gc
, mask_img
, 0, 0, 0, 0,
520 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
522 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
523 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
525 XDestroyImage (ximg
);
526 x_destroy_x_image (mask_img
);
529 #endif /* HAVE_X_WINDOWS */
532 /***********************************************************************
534 ***********************************************************************/
536 /* List of supported image types. Use define_image_type to add new
537 types. Use lookup_image_type to find a type for a given symbol. */
539 static struct image_type
*image_types
;
541 /* The symbol `xbm' which is used as the type symbol for XBM images. */
543 static Lisp_Object Qxbm
;
547 Lisp_Object QCascent
, QCmargin
, QCrelief
;
548 Lisp_Object QCconversion
;
549 static Lisp_Object QCheuristic_mask
;
550 static Lisp_Object QCcolor_symbols
;
551 static Lisp_Object QCindex
, QCmatrix
, QCcolor_adjustment
, QCmask
, QCgeometry
;
552 static Lisp_Object QCcrop
, QCrotation
;
556 static Lisp_Object Qcount
, Qextension_data
, Qdelay
;
557 static Lisp_Object Qlaplace
, Qemboss
, Qedge_detection
, Qheuristic
;
559 /* Forward function prototypes. */
561 static struct image_type
*lookup_image_type (Lisp_Object
);
562 static void x_laplace (struct frame
*, struct image
*);
563 static void x_emboss (struct frame
*, struct image
*);
564 static void x_build_heuristic_mask (struct frame
*, struct image
*,
567 extern Lisp_Object Vlibrary_cache
;
568 #define CACHE_IMAGE_TYPE(type, status) \
569 do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
571 #define CACHE_IMAGE_TYPE(type, status)
574 #define ADD_IMAGE_TYPE(type) \
575 do { Vimage_types = Fcons (type, Vimage_types); } while (0)
577 /* Define a new image type from TYPE. This adds a copy of TYPE to
578 image_types and caches the loading status of TYPE. */
580 static struct image_type
*
581 define_image_type (struct image_type
*type
)
583 struct image_type
*p
= NULL
;
584 Lisp_Object target_type
= *type
->type
;
589 for (p
= image_types
; p
; p
= p
->next
)
590 if (EQ (*p
->type
, target_type
))
595 #if defined HAVE_NTGUI && defined WINDOWSNT
596 /* If we failed to load the library before, don't try again. */
597 Lisp_Object tested
= Fassq (target_type
, Vlibrary_cache
);
598 if (CONSP (tested
) && NILP (XCDR (tested
)))
603 type_valid
= type
->init ();
604 CACHE_IMAGE_TYPE (target_type
, type_valid
? Qt
: Qnil
);
610 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
611 The initialized data segment is read-only. */
612 p
= xmalloc (sizeof *p
);
614 p
->next
= image_types
;
624 /* Value is true if OBJECT is a valid Lisp image specification. A
625 valid image specification is a list whose car is the symbol
626 `image', and whose rest is a property list. The property list must
627 contain a value for key `:type'. That value must be the name of a
628 supported image type. The rest of the property list depends on the
632 valid_image_p (Lisp_Object object
)
640 for (tem
= XCDR (object
); CONSP (tem
); tem
= XCDR (tem
))
641 if (EQ (XCAR (tem
), QCtype
))
644 if (CONSP (tem
) && SYMBOLP (XCAR (tem
)))
646 struct image_type
*type
;
647 type
= lookup_image_type (XCAR (tem
));
649 valid_p
= type
->valid_p (object
);
660 /* Log error message with format string FORMAT and argument ARG.
661 Signaling an error, e.g. when an image cannot be loaded, is not a
662 good idea because this would interrupt redisplay, and the error
663 message display would lead to another redisplay. This function
664 therefore simply displays a message. */
667 image_error (const char *format
, Lisp_Object arg1
, Lisp_Object arg2
)
669 add_to_log (format
, arg1
, arg2
);
674 /***********************************************************************
676 ***********************************************************************/
678 enum image_value_type
680 IMAGE_DONT_CHECK_VALUE_TYPE
,
682 IMAGE_STRING_OR_NIL_VALUE
,
684 IMAGE_POSITIVE_INTEGER_VALUE
,
685 IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
,
686 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
689 IMAGE_FUNCTION_VALUE
,
694 /* Structure used when parsing image specifications. */
698 /* Name of keyword. */
701 /* The type of value allowed. */
702 enum image_value_type type
;
704 /* True means key must be present. */
707 /* Used to recognize duplicate keywords in a property list. */
710 /* The value that was found. */
715 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
716 has the format (image KEYWORD VALUE ...). One of the keyword/
717 value pairs must be `:type TYPE'. KEYWORDS is a vector of
718 image_keywords structures of size NKEYWORDS describing other
719 allowed keyword/value pairs. Value is true if SPEC is valid. */
722 parse_image_spec (Lisp_Object spec
, struct image_keyword
*keywords
,
723 int nkeywords
, Lisp_Object type
)
732 while (CONSP (plist
))
734 Lisp_Object key
, value
;
736 /* First element of a pair must be a symbol. */
738 plist
= XCDR (plist
);
742 /* There must follow a value. */
745 value
= XCAR (plist
);
746 plist
= XCDR (plist
);
748 /* Find key in KEYWORDS. Error if not found. */
749 for (i
= 0; i
< nkeywords
; ++i
)
750 if (strcmp (keywords
[i
].name
, SSDATA (SYMBOL_NAME (key
))) == 0)
756 /* Record that we recognized the keyword. If a keywords
757 was found more than once, it's an error. */
758 keywords
[i
].value
= value
;
759 if (keywords
[i
].count
> 1)
763 /* Check type of value against allowed type. */
764 switch (keywords
[i
].type
)
766 case IMAGE_STRING_VALUE
:
767 if (!STRINGP (value
))
771 case IMAGE_STRING_OR_NIL_VALUE
:
772 if (!STRINGP (value
) && !NILP (value
))
776 case IMAGE_SYMBOL_VALUE
:
777 if (!SYMBOLP (value
))
781 case IMAGE_POSITIVE_INTEGER_VALUE
:
782 if (! RANGED_INTEGERP (1, value
, INT_MAX
))
786 case IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
:
787 if (RANGED_INTEGERP (0, value
, INT_MAX
))
790 && RANGED_INTEGERP (0, XCAR (value
), INT_MAX
)
791 && RANGED_INTEGERP (0, XCDR (value
), INT_MAX
))
795 case IMAGE_ASCENT_VALUE
:
796 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
798 else if (RANGED_INTEGERP (0, value
, 100))
802 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
803 /* Unlike the other integer-related cases, this one does not
804 verify that VALUE fits in 'int'. This is because callers
806 if (!INTEGERP (value
) || XINT (value
) < 0)
810 case IMAGE_DONT_CHECK_VALUE_TYPE
:
813 case IMAGE_FUNCTION_VALUE
:
814 value
= indirect_function (value
);
815 if (!NILP (Ffunctionp (value
)))
819 case IMAGE_NUMBER_VALUE
:
820 if (!INTEGERP (value
) && !FLOATP (value
))
824 case IMAGE_INTEGER_VALUE
:
825 if (! TYPE_RANGED_INTEGERP (int, value
))
829 case IMAGE_BOOL_VALUE
:
830 if (!NILP (value
) && !EQ (value
, Qt
))
839 if (EQ (key
, QCtype
) && !EQ (type
, value
))
843 /* Check that all mandatory fields are present. */
844 for (i
= 0; i
< nkeywords
; ++i
)
845 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
852 /* Return the value of KEY in image specification SPEC. Value is nil
853 if KEY is not present in SPEC. Set *FOUND depending on whether KEY
854 was found in SPEC. */
857 image_spec_value (Lisp_Object spec
, Lisp_Object key
, bool *found
)
861 eassert (valid_image_p (spec
));
863 for (tail
= XCDR (spec
);
864 CONSP (tail
) && CONSP (XCDR (tail
));
865 tail
= XCDR (XCDR (tail
)))
867 if (EQ (XCAR (tail
), key
))
871 return XCAR (XCDR (tail
));
881 DEFUN ("image-size", Fimage_size
, Simage_size
, 1, 3, 0,
882 doc
: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
883 PIXELS non-nil means return the size in pixels, otherwise return the
884 size in canonical character units.
885 FRAME is the frame on which the image will be displayed. FRAME nil
886 or omitted means use the selected frame. */)
887 (Lisp_Object spec
, Lisp_Object pixels
, Lisp_Object frame
)
892 if (valid_image_p (spec
))
894 struct frame
*f
= decode_window_system_frame (frame
);
895 ptrdiff_t id
= lookup_image (f
, spec
);
896 struct image
*img
= IMAGE_FROM_ID (f
, id
);
897 int width
= img
->width
+ 2 * img
->hmargin
;
898 int height
= img
->height
+ 2 * img
->vmargin
;
901 size
= Fcons (make_float ((double) width
/ FRAME_COLUMN_WIDTH (f
)),
902 make_float ((double) height
/ FRAME_LINE_HEIGHT (f
)));
904 size
= Fcons (make_number (width
), make_number (height
));
907 error ("Invalid image specification");
913 DEFUN ("image-mask-p", Fimage_mask_p
, Simage_mask_p
, 1, 2, 0,
914 doc
: /* Return t if image SPEC has a mask bitmap.
915 FRAME is the frame on which the image will be displayed. FRAME nil
916 or omitted means use the selected frame. */)
917 (Lisp_Object spec
, Lisp_Object frame
)
922 if (valid_image_p (spec
))
924 struct frame
*f
= decode_window_system_frame (frame
);
925 ptrdiff_t id
= lookup_image (f
, spec
);
926 struct image
*img
= IMAGE_FROM_ID (f
, id
);
931 error ("Invalid image specification");
936 DEFUN ("image-metadata", Fimage_metadata
, Simage_metadata
, 1, 2, 0,
937 doc
: /* Return metadata for image SPEC.
938 FRAME is the frame on which the image will be displayed. FRAME nil
939 or omitted means use the selected frame. */)
940 (Lisp_Object spec
, Lisp_Object frame
)
945 if (valid_image_p (spec
))
947 struct frame
*f
= decode_window_system_frame (frame
);
948 ptrdiff_t id
= lookup_image (f
, spec
);
949 struct image
*img
= IMAGE_FROM_ID (f
, id
);
950 ext
= img
->lisp_data
;
957 /***********************************************************************
958 Image type independent image structures
959 ***********************************************************************/
961 #define MAX_IMAGE_SIZE 10.0
962 /* Allocate and return a new image structure for image specification
963 SPEC. SPEC has a hash value of HASH. */
965 static struct image
*
966 make_image (Lisp_Object spec
, EMACS_UINT hash
)
968 struct image
*img
= xzalloc (sizeof *img
);
969 Lisp_Object file
= image_spec_value (spec
, QCfile
, NULL
);
971 eassert (valid_image_p (spec
));
972 img
->dependencies
= NILP (file
) ? Qnil
: list1 (file
);
973 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
974 eassert (img
->type
!= NULL
);
976 img
->lisp_data
= Qnil
;
977 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
979 img
->corners
[BOT_CORNER
] = -1; /* Full image */
984 /* Free image IMG which was used on frame F, including its resources. */
987 free_image (struct frame
*f
, struct image
*img
)
991 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
993 /* Remove IMG from the hash table of its cache. */
995 img
->prev
->next
= img
->next
;
997 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
1000 img
->next
->prev
= img
->prev
;
1002 c
->images
[img
->id
] = NULL
;
1004 /* Free resources, then free IMG. */
1005 img
->type
->free (f
, img
);
1010 /* Return true if the given widths and heights are valid for display. */
1013 check_image_size (struct frame
*f
, int width
, int height
)
1017 if (width
<= 0 || height
<= 0)
1020 if (INTEGERP (Vmax_image_size
))
1021 return (width
<= XINT (Vmax_image_size
)
1022 && height
<= XINT (Vmax_image_size
));
1023 else if (FLOATP (Vmax_image_size
))
1027 w
= FRAME_PIXEL_WIDTH (f
);
1028 h
= FRAME_PIXEL_HEIGHT (f
);
1031 w
= h
= 1024; /* Arbitrary size for unknown frame. */
1032 return (width
<= XFLOAT_DATA (Vmax_image_size
) * w
1033 && height
<= XFLOAT_DATA (Vmax_image_size
) * h
);
1039 /* Prepare image IMG for display on frame F. Must be called before
1040 drawing an image. */
1043 prepare_image_for_display (struct frame
*f
, struct image
*img
)
1045 /* We're about to display IMG, so set its timestamp to `now'. */
1046 img
->timestamp
= current_emacs_time ();
1048 /* If IMG doesn't have a pixmap yet, load it now, using the image
1049 type dependent loader function. */
1050 if (img
->pixmap
== NO_PIXMAP
&& !img
->load_failed_p
)
1051 img
->load_failed_p
= ! img
->type
->load (f
, img
);
1056 /* Value is the number of pixels for the ascent of image IMG when
1057 drawn in face FACE. */
1060 image_ascent (struct image
*img
, struct face
*face
, struct glyph_slice
*slice
)
1065 if (slice
->height
== img
->height
)
1066 height
= img
->height
+ img
->vmargin
;
1067 else if (slice
->y
== 0)
1068 height
= slice
->height
+ img
->vmargin
;
1070 height
= slice
->height
;
1072 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
1077 /* W32 specific version. Why?. ++kfs */
1078 ascent
= height
/ 2 - (FONT_DESCENT (face
->font
)
1079 - FONT_BASE (face
->font
)) / 2;
1081 /* This expression is arranged so that if the image can't be
1082 exactly centered, it will be moved slightly up. This is
1083 because a typical font is `top-heavy' (due to the presence
1084 uppercase letters), so the image placement should err towards
1085 being top-heavy too. It also just generally looks better. */
1086 ascent
= (height
+ FONT_BASE (face
->font
)
1087 - FONT_DESCENT (face
->font
) + 1) / 2;
1088 #endif /* HAVE_NTGUI */
1091 ascent
= height
/ 2;
1094 ascent
= height
* (img
->ascent
/ 100.0);
1100 /* Image background colors. */
1102 /* Find the "best" corner color of a bitmap.
1103 On W32, XIMG is assumed to a device context with the bitmap selected. */
1105 static RGB_PIXEL_COLOR
1106 four_corners_best (XImagePtr_or_DC ximg
, int *corners
,
1107 unsigned long width
, unsigned long height
)
1109 RGB_PIXEL_COLOR corner_pixels
[4], best
IF_LINT (= 0);
1112 if (corners
&& corners
[BOT_CORNER
] >= 0)
1114 /* Get the colors at the corner_pixels of ximg. */
1115 corner_pixels
[0] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[TOP_CORNER
]);
1116 corner_pixels
[1] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[TOP_CORNER
]);
1117 corner_pixels
[2] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[BOT_CORNER
] - 1);
1118 corner_pixels
[3] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[BOT_CORNER
] - 1);
1122 /* Get the colors at the corner_pixels of ximg. */
1123 corner_pixels
[0] = GET_PIXEL (ximg
, 0, 0);
1124 corner_pixels
[1] = GET_PIXEL (ximg
, width
- 1, 0);
1125 corner_pixels
[2] = GET_PIXEL (ximg
, width
- 1, height
- 1);
1126 corner_pixels
[3] = GET_PIXEL (ximg
, 0, height
- 1);
1128 /* Choose the most frequently found color as background. */
1129 for (i
= best_count
= 0; i
< 4; ++i
)
1133 for (j
= n
= 0; j
< 4; ++j
)
1134 if (corner_pixels
[i
] == corner_pixels
[j
])
1138 best
= corner_pixels
[i
], best_count
= n
;
1144 /* Portability macros */
1148 #define Destroy_Image(img_dc, prev) \
1149 do { SelectObject (img_dc, prev); DeleteDC (img_dc); } while (0)
1151 #define Free_Pixmap(display, pixmap) \
1152 DeleteObject (pixmap)
1154 #elif defined (HAVE_NS)
1156 #define Destroy_Image(ximg, dummy) \
1157 ns_release_object (ximg)
1159 #define Free_Pixmap(display, pixmap) \
1160 ns_release_object (pixmap)
1164 #define Destroy_Image(ximg, dummy) \
1165 XDestroyImage (ximg)
1167 #define Free_Pixmap(display, pixmap) \
1168 XFreePixmap (display, pixmap)
1170 #endif /* !HAVE_NTGUI && !HAVE_NS */
1173 /* Return the `background' field of IMG. If IMG doesn't have one yet,
1174 it is guessed heuristically. If non-zero, XIMG is an existing
1175 XImage object (or device context with the image selected on W32) to
1176 use for the heuristic. */
1179 image_background (struct image
*img
, struct frame
*f
, XImagePtr_or_DC ximg
)
1181 if (! img
->background_valid
)
1182 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1184 bool free_ximg
= !ximg
;
1187 #endif /* HAVE_NTGUI */
1192 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
1193 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
1195 HDC frame_dc
= get_frame_dc (f
);
1196 ximg
= CreateCompatibleDC (frame_dc
);
1197 release_frame_dc (f
, frame_dc
);
1198 prev
= SelectObject (ximg
, img
->pixmap
);
1199 #endif /* !HAVE_NTGUI */
1202 img
->background
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
1205 Destroy_Image (ximg
, prev
);
1207 img
->background_valid
= 1;
1210 return img
->background
;
1213 /* Return the `background_transparent' field of IMG. If IMG doesn't
1214 have one yet, it is guessed heuristically. If non-zero, MASK is an
1215 existing XImage object to use for the heuristic. */
1218 image_background_transparent (struct image
*img
, struct frame
*f
, XImagePtr_or_DC mask
)
1220 if (! img
->background_transparent_valid
)
1221 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1225 bool free_mask
= !mask
;
1228 #endif /* HAVE_NTGUI */
1233 mask
= XGetImage (FRAME_X_DISPLAY (f
), img
->mask
,
1234 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
1236 HDC frame_dc
= get_frame_dc (f
);
1237 mask
= CreateCompatibleDC (frame_dc
);
1238 release_frame_dc (f
, frame_dc
);
1239 prev
= SelectObject (mask
, img
->mask
);
1240 #endif /* HAVE_NTGUI */
1243 img
->background_transparent
1244 = (four_corners_best (mask
, img
->corners
, img
->width
, img
->height
) == PIX_MASK_RETAIN
);
1247 Destroy_Image (mask
, prev
);
1250 img
->background_transparent
= 0;
1252 img
->background_transparent_valid
= 1;
1255 return img
->background_transparent
;
1259 /***********************************************************************
1260 Helper functions for X image types
1261 ***********************************************************************/
1263 /* Clear X resources of image IMG on frame F. PIXMAP_P means free the
1264 pixmap if any. MASK_P means clear the mask pixmap if any.
1265 COLORS_P means free colors allocated for the image, if any. */
1268 x_clear_image_1 (struct frame
*f
, struct image
*img
, bool pixmap_p
,
1269 bool mask_p
, bool colors_p
)
1271 if (pixmap_p
&& img
->pixmap
)
1273 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
1274 img
->pixmap
= NO_PIXMAP
;
1275 /* NOTE (HAVE_NS): background color is NOT an indexed color! */
1276 img
->background_valid
= 0;
1279 if (mask_p
&& img
->mask
)
1281 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
1282 img
->mask
= NO_PIXMAP
;
1283 img
->background_transparent_valid
= 0;
1286 if (colors_p
&& img
->ncolors
)
1288 /* W32_TODO: color table support. */
1289 #ifdef HAVE_X_WINDOWS
1290 x_free_colors (f
, img
->colors
, img
->ncolors
);
1291 #endif /* HAVE_X_WINDOWS */
1292 xfree (img
->colors
);
1299 /* Free X resources of image IMG which is used on frame F. */
1302 x_clear_image (struct frame
*f
, struct image
*img
)
1305 x_clear_image_1 (f
, img
, 1, 1, 1);
1310 /* Allocate color COLOR_NAME for image IMG on frame F. If color
1311 cannot be allocated, use DFLT. Add a newly allocated color to
1312 IMG->colors, so that it can be freed again. Value is the pixel
1315 static unsigned long
1316 x_alloc_image_color (struct frame
*f
, struct image
*img
, Lisp_Object color_name
,
1320 unsigned long result
;
1322 eassert (STRINGP (color_name
));
1324 if (x_defined_color (f
, SSDATA (color_name
), &color
, 1)
1325 && img
->ncolors
< min (min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *img
->colors
,
1328 /* This isn't called frequently so we get away with simply
1329 reallocating the color vector to the needed size, here. */
1330 ptrdiff_t ncolors
= img
->ncolors
+ 1;
1331 img
->colors
= xrealloc (img
->colors
, ncolors
* sizeof *img
->colors
);
1332 img
->colors
[ncolors
- 1] = color
.pixel
;
1333 img
->ncolors
= ncolors
;
1334 result
= color
.pixel
;
1344 /***********************************************************************
1346 ***********************************************************************/
1348 static void cache_image (struct frame
*f
, struct image
*img
);
1350 /* Return a new, initialized image cache that is allocated from the
1351 heap. Call free_image_cache to free an image cache. */
1353 struct image_cache
*
1354 make_image_cache (void)
1356 struct image_cache
*c
= xzalloc (sizeof *c
);
1360 c
->images
= xmalloc (size
* sizeof *c
->images
);
1362 size
= IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
1363 c
->buckets
= xzalloc (size
);
1368 /* Find an image matching SPEC in the cache, and return it. If no
1369 image is found, return NULL. */
1370 static struct image
*
1371 search_image_cache (struct frame
*f
, Lisp_Object spec
, EMACS_UINT hash
)
1374 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1375 int i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1377 if (!c
) return NULL
;
1379 /* If the image spec does not specify a background color, the cached
1380 image must have the same background color as the current frame.
1381 The foreground color must also match, for the sake of monochrome
1384 In fact, we could ignore the foreground color matching condition
1385 for color images, or if the image spec specifies :foreground;
1386 similarly we could ignore the background color matching condition
1387 for formats that don't use transparency (such as jpeg), or if the
1388 image spec specifies :background. However, the extra memory
1389 usage is probably negligible in practice, so we don't bother. */
1391 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
1392 if (img
->hash
== hash
1393 && !NILP (Fequal (img
->spec
, spec
))
1394 && img
->frame_foreground
== FRAME_FOREGROUND_PIXEL (f
)
1395 && img
->frame_background
== FRAME_BACKGROUND_PIXEL (f
))
1401 /* Search frame F for an image with spec SPEC, and free it. */
1404 uncache_image (struct frame
*f
, Lisp_Object spec
)
1406 struct image
*img
= search_image_cache (f
, spec
, sxhash (spec
, 0));
1409 free_image (f
, img
);
1410 /* As display glyphs may still be referring to the image ID, we
1411 must garbage the frame (Bug#6426). */
1412 SET_FRAME_GARBAGED (f
);
1417 /* Free image cache of frame F. Be aware that X frames share images
1421 free_image_cache (struct frame
*f
)
1423 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1428 /* Cache should not be referenced by any frame when freed. */
1429 eassert (c
->refcount
== 0);
1431 for (i
= 0; i
< c
->used
; ++i
)
1432 free_image (f
, c
->images
[i
]);
1436 FRAME_IMAGE_CACHE (f
) = NULL
;
1441 /* Clear image cache of frame F. FILTER=t means free all images.
1442 FILTER=nil means clear only images that haven't been
1443 displayed for some time.
1444 Else, only free the images which have FILTER in their `dependencies'.
1445 Should be called from time to time to reduce the number of loaded images.
1446 If image-cache-eviction-delay is non-nil, this frees images in the cache
1447 which weren't displayed for at least that many seconds. */
1450 clear_image_cache (struct frame
*f
, Lisp_Object filter
)
1452 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1456 ptrdiff_t i
, nfreed
= 0;
1458 /* Block input so that we won't be interrupted by a SIGIO
1459 while being in an inconsistent state. */
1464 /* Filter image cache. */
1465 for (i
= 0; i
< c
->used
; ++i
)
1467 struct image
*img
= c
->images
[i
];
1468 if (img
&& (EQ (Qt
, filter
)
1469 || !NILP (Fmember (filter
, img
->dependencies
))))
1471 free_image (f
, img
);
1476 else if (INTEGERP (Vimage_cache_eviction_delay
))
1478 /* Free cache based on timestamp. */
1481 ptrdiff_t nimages
= 0;
1483 for (i
= 0; i
< c
->used
; ++i
)
1487 /* If the number of cached images has grown unusually large,
1488 decrease the cache eviction delay (Bug#6230). */
1489 delay
= XINT (Vimage_cache_eviction_delay
);
1491 delay
= 1600 * delay
/ nimages
/ nimages
;
1492 delay
= max (delay
, 1);
1494 t
= current_emacs_time ();
1495 old
= sub_emacs_time (t
, EMACS_TIME_FROM_DOUBLE (delay
));
1497 for (i
= 0; i
< c
->used
; ++i
)
1499 struct image
*img
= c
->images
[i
];
1500 if (img
&& EMACS_TIME_LT (img
->timestamp
, old
))
1502 free_image (f
, img
);
1508 /* We may be clearing the image cache because, for example,
1509 Emacs was iconified for a longer period of time. In that
1510 case, current matrices may still contain references to
1511 images freed above. So, clear these matrices. */
1514 Lisp_Object tail
, frame
;
1516 FOR_EACH_FRAME (tail
, frame
)
1518 struct frame
*fr
= XFRAME (frame
);
1519 if (FRAME_IMAGE_CACHE (fr
) == c
)
1520 clear_current_matrices (fr
);
1523 ++windows_or_buffers_changed
;
1531 clear_image_caches (Lisp_Object filter
)
1533 /* FIXME: We want to do
1534 * struct terminal *t;
1535 * for (t = terminal_list; t; t = t->next_terminal)
1536 * clear_image_cache (t, filter); */
1537 Lisp_Object tail
, frame
;
1538 FOR_EACH_FRAME (tail
, frame
)
1539 if (FRAME_WINDOW_P (XFRAME (frame
)))
1540 clear_image_cache (XFRAME (frame
), filter
);
1543 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
1545 doc
: /* Clear the image cache.
1546 FILTER nil or a frame means clear all images in the selected frame.
1547 FILTER t means clear the image caches of all frames.
1548 Anything else, means only clear those images which refer to FILTER,
1549 which is then usually a filename. */)
1550 (Lisp_Object filter
)
1552 if (!(EQ (filter
, Qnil
) || FRAMEP (filter
)))
1553 clear_image_caches (filter
);
1555 clear_image_cache (decode_window_system_frame (filter
), Qt
);
1561 DEFUN ("image-flush", Fimage_flush
, Simage_flush
,
1563 doc
: /* Fush the image with specification SPEC on frame FRAME.
1564 This removes the image from the Emacs image cache. If SPEC specifies
1565 an image file, the next redisplay of this image will read from the
1566 current contents of that file.
1568 FRAME nil or omitted means use the selected frame.
1569 FRAME t means refresh the image on all frames. */)
1570 (Lisp_Object spec
, Lisp_Object frame
)
1572 if (!valid_image_p (spec
))
1573 error ("Invalid image specification");
1578 FOR_EACH_FRAME (tail
, frame
)
1580 struct frame
*f
= XFRAME (frame
);
1581 if (FRAME_WINDOW_P (f
))
1582 uncache_image (f
, spec
);
1586 uncache_image (decode_window_system_frame (frame
), spec
);
1592 /* Compute masks and transform image IMG on frame F, as specified
1593 by the image's specification, */
1596 postprocess_image (struct frame
*f
, struct image
*img
)
1598 /* Manipulation of the image's mask. */
1601 Lisp_Object conversion
, spec
;
1606 /* `:heuristic-mask t'
1608 means build a mask heuristically.
1609 `:heuristic-mask (R G B)'
1610 `:mask (heuristic (R G B))'
1611 means build a mask from color (R G B) in the
1614 means remove a mask, if any. */
1616 mask
= image_spec_value (spec
, QCheuristic_mask
, NULL
);
1618 x_build_heuristic_mask (f
, img
, mask
);
1623 mask
= image_spec_value (spec
, QCmask
, &found_p
);
1625 if (EQ (mask
, Qheuristic
))
1626 x_build_heuristic_mask (f
, img
, Qt
);
1627 else if (CONSP (mask
)
1628 && EQ (XCAR (mask
), Qheuristic
))
1630 if (CONSP (XCDR (mask
)))
1631 x_build_heuristic_mask (f
, img
, XCAR (XCDR (mask
)));
1633 x_build_heuristic_mask (f
, img
, XCDR (mask
));
1635 else if (NILP (mask
) && found_p
&& img
->mask
)
1637 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
1638 img
->mask
= NO_PIXMAP
;
1643 /* Should we apply an image transformation algorithm? */
1644 conversion
= image_spec_value (spec
, QCconversion
, NULL
);
1645 if (EQ (conversion
, Qdisabled
))
1646 x_disable_image (f
, img
);
1647 else if (EQ (conversion
, Qlaplace
))
1649 else if (EQ (conversion
, Qemboss
))
1651 else if (CONSP (conversion
)
1652 && EQ (XCAR (conversion
), Qedge_detection
))
1655 tem
= XCDR (conversion
);
1657 x_edge_detection (f
, img
,
1658 Fplist_get (tem
, QCmatrix
),
1659 Fplist_get (tem
, QCcolor_adjustment
));
1665 /* Return the id of image with Lisp specification SPEC on frame F.
1666 SPEC must be a valid Lisp image specification (see valid_image_p). */
1669 lookup_image (struct frame
*f
, Lisp_Object spec
)
1674 /* F must be a window-system frame, and SPEC must be a valid image
1676 eassert (FRAME_WINDOW_P (f
));
1677 eassert (valid_image_p (spec
));
1679 /* Look up SPEC in the hash table of the image cache. */
1680 hash
= sxhash (spec
, 0);
1681 img
= search_image_cache (f
, spec
, hash
);
1682 if (img
&& img
->load_failed_p
)
1684 free_image (f
, img
);
1688 /* If not found, create a new image and cache it. */
1692 img
= make_image (spec
, hash
);
1693 cache_image (f
, img
);
1694 img
->load_failed_p
= ! img
->type
->load (f
, img
);
1695 img
->frame_foreground
= FRAME_FOREGROUND_PIXEL (f
);
1696 img
->frame_background
= FRAME_BACKGROUND_PIXEL (f
);
1698 /* If we can't load the image, and we don't have a width and
1699 height, use some arbitrary width and height so that we can
1700 draw a rectangle for it. */
1701 if (img
->load_failed_p
)
1705 value
= image_spec_value (spec
, QCwidth
, NULL
);
1706 img
->width
= (INTEGERP (value
)
1707 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
1708 value
= image_spec_value (spec
, QCheight
, NULL
);
1709 img
->height
= (INTEGERP (value
)
1710 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
1714 /* Handle image type independent image attributes
1715 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
1716 `:background COLOR'. */
1717 Lisp_Object ascent
, margin
, relief
, bg
;
1720 ascent
= image_spec_value (spec
, QCascent
, NULL
);
1721 if (INTEGERP (ascent
))
1722 img
->ascent
= XFASTINT (ascent
);
1723 else if (EQ (ascent
, Qcenter
))
1724 img
->ascent
= CENTERED_IMAGE_ASCENT
;
1726 margin
= image_spec_value (spec
, QCmargin
, NULL
);
1727 if (INTEGERP (margin
))
1728 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
1729 else if (CONSP (margin
))
1731 img
->hmargin
= XFASTINT (XCAR (margin
));
1732 img
->vmargin
= XFASTINT (XCDR (margin
));
1735 relief
= image_spec_value (spec
, QCrelief
, NULL
);
1736 relief_bound
= INT_MAX
- max (img
->hmargin
, img
->vmargin
);
1737 if (RANGED_INTEGERP (- relief_bound
, relief
, relief_bound
))
1739 img
->relief
= XINT (relief
);
1740 img
->hmargin
+= eabs (img
->relief
);
1741 img
->vmargin
+= eabs (img
->relief
);
1744 if (! img
->background_valid
)
1746 bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
1750 = x_alloc_image_color (f
, img
, bg
,
1751 FRAME_BACKGROUND_PIXEL (f
));
1752 img
->background_valid
= 1;
1756 /* Do image transformations and compute masks, unless we
1757 don't have the image yet. */
1758 if (!EQ (*img
->type
->type
, Qpostscript
))
1759 postprocess_image (f
, img
);
1765 /* We're using IMG, so set its timestamp to `now'. */
1766 img
->timestamp
= current_emacs_time ();
1768 /* Value is the image id. */
1773 /* Cache image IMG in the image cache of frame F. */
1776 cache_image (struct frame
*f
, struct image
*img
)
1778 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1781 /* Find a free slot in c->images. */
1782 for (i
= 0; i
< c
->used
; ++i
)
1783 if (c
->images
[i
] == NULL
)
1786 /* If no free slot found, maybe enlarge c->images. */
1787 if (i
== c
->used
&& c
->used
== c
->size
)
1788 c
->images
= xpalloc (c
->images
, &c
->size
, 1, -1, sizeof *c
->images
);
1790 /* Add IMG to c->images, and assign IMG an id. */
1796 /* Add IMG to the cache's hash table. */
1797 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1798 img
->next
= c
->buckets
[i
];
1800 img
->next
->prev
= img
;
1802 c
->buckets
[i
] = img
;
1806 /* Call FN on every image in the image cache of frame F. Used to mark
1807 Lisp Objects in the image cache. */
1809 /* Mark Lisp objects in image IMG. */
1812 mark_image (struct image
*img
)
1814 mark_object (img
->spec
);
1815 mark_object (img
->dependencies
);
1817 if (!NILP (img
->lisp_data
))
1818 mark_object (img
->lisp_data
);
1823 mark_image_cache (struct image_cache
*c
)
1828 for (i
= 0; i
< c
->used
; ++i
)
1830 mark_image (c
->images
[i
]);
1836 /***********************************************************************
1837 X / NS / W32 support code
1838 ***********************************************************************/
1842 /* Macro for defining functions that will be loaded from image DLLs. */
1843 #define DEF_IMGLIB_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args
1845 /* Macro for loading those image functions from the library. */
1846 #define LOAD_IMGLIB_FN(lib,func) { \
1847 fn_##func = (void *) GetProcAddress (lib, #func); \
1848 if (!fn_##func) return 0; \
1851 #endif /* WINDOWSNT */
1853 /* Return true if XIMG's size WIDTH x HEIGHT doesn't break the
1855 WIDTH and HEIGHT must both be positive.
1856 If XIMG is null, assume it is a bitmap. */
1858 x_check_image_size (XImagePtr ximg
, int width
, int height
)
1860 #ifdef HAVE_X_WINDOWS
1861 /* Respect Xlib's limits: it cannot deal with images that have more
1862 than INT_MAX (and/or UINT_MAX) bytes. And respect Emacs's limits
1863 of PTRDIFF_MAX (and/or SIZE_MAX) bytes for any object. */
1866 XLIB_BYTES_MAX
= min (INT_MAX
, UINT_MAX
),
1867 X_IMAGE_BYTES_MAX
= min (XLIB_BYTES_MAX
, min (PTRDIFF_MAX
, SIZE_MAX
))
1870 int bitmap_pad
, depth
, bytes_per_line
;
1873 bitmap_pad
= ximg
->bitmap_pad
;
1874 depth
= ximg
->depth
;
1875 bytes_per_line
= ximg
->bytes_per_line
;
1881 bytes_per_line
= (width
>> 3) + ((width
& 7) != 0);
1883 return (width
<= (INT_MAX
- (bitmap_pad
- 1)) / depth
1884 && height
<= X_IMAGE_BYTES_MAX
/ bytes_per_line
);
1886 /* FIXME: Implement this check for the HAVE_NS and HAVE_NTGUI cases.
1887 For now, assume that every image size is allowed on these systems. */
1892 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
1893 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
1894 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
1895 via xmalloc. Print error messages via image_error if an error
1896 occurs. Value is true if successful.
1898 On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
1899 should indicate the bit depth of the image. */
1902 x_create_x_image_and_pixmap (struct frame
*f
, int width
, int height
, int depth
,
1903 XImagePtr
*ximg
, Pixmap
*pixmap
)
1905 #ifdef HAVE_X_WINDOWS
1906 Display
*display
= FRAME_X_DISPLAY (f
);
1907 Window window
= FRAME_X_WINDOW (f
);
1908 Screen
*screen
= FRAME_X_SCREEN (f
);
1910 eassert (input_blocked_p ());
1913 depth
= DefaultDepthOfScreen (screen
);
1914 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
1915 depth
, ZPixmap
, 0, NULL
, width
, height
,
1916 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
1919 image_error ("Unable to allocate X image", Qnil
, Qnil
);
1923 if (! x_check_image_size (*ximg
, width
, height
))
1925 x_destroy_x_image (*ximg
);
1927 image_error ("Image too large (%dx%d)",
1928 make_number (width
), make_number (height
));
1932 /* Allocate image raster. */
1933 (*ximg
)->data
= xmalloc ((*ximg
)->bytes_per_line
* height
);
1935 /* Allocate a pixmap of the same size. */
1936 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
1937 if (*pixmap
== NO_PIXMAP
)
1939 x_destroy_x_image (*ximg
);
1941 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
1946 #endif /* HAVE_X_WINDOWS */
1950 BITMAPINFOHEADER
*header
;
1952 int scanline_width_bits
;
1954 int palette_colors
= 0;
1959 if (depth
!= 1 && depth
!= 4 && depth
!= 8
1960 && depth
!= 16 && depth
!= 24 && depth
!= 32)
1962 image_error ("Invalid image bit depth specified", Qnil
, Qnil
);
1966 scanline_width_bits
= width
* depth
;
1967 remainder
= scanline_width_bits
% 32;
1970 scanline_width_bits
+= 32 - remainder
;
1972 /* Bitmaps with a depth less than 16 need a palette. */
1973 /* BITMAPINFO structure already contains the first RGBQUAD. */
1975 palette_colors
= 1 << (depth
- 1);
1977 *ximg
= xmalloc (sizeof (XImage
) + palette_colors
* sizeof (RGBQUAD
));
1979 header
= &(*ximg
)->info
.bmiHeader
;
1980 memset (&(*ximg
)->info
, 0, sizeof (BITMAPINFO
));
1981 header
->biSize
= sizeof (*header
);
1982 header
->biWidth
= width
;
1983 header
->biHeight
= -height
; /* negative indicates a top-down bitmap. */
1984 header
->biPlanes
= 1;
1985 header
->biBitCount
= depth
;
1986 header
->biCompression
= BI_RGB
;
1987 header
->biClrUsed
= palette_colors
;
1989 /* TODO: fill in palette. */
1992 (*ximg
)->info
.bmiColors
[0].rgbBlue
= 0;
1993 (*ximg
)->info
.bmiColors
[0].rgbGreen
= 0;
1994 (*ximg
)->info
.bmiColors
[0].rgbRed
= 0;
1995 (*ximg
)->info
.bmiColors
[0].rgbReserved
= 0;
1996 (*ximg
)->info
.bmiColors
[1].rgbBlue
= 255;
1997 (*ximg
)->info
.bmiColors
[1].rgbGreen
= 255;
1998 (*ximg
)->info
.bmiColors
[1].rgbRed
= 255;
1999 (*ximg
)->info
.bmiColors
[1].rgbReserved
= 0;
2002 hdc
= get_frame_dc (f
);
2004 /* Create a DIBSection and raster array for the bitmap,
2005 and store its handle in *pixmap. */
2006 *pixmap
= CreateDIBSection (hdc
, &((*ximg
)->info
),
2007 (depth
< 16) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
,
2008 /* casting avoids a GCC warning */
2009 (void **)&((*ximg
)->data
), NULL
, 0);
2011 /* Realize display palette and garbage all frames. */
2012 release_frame_dc (f
, hdc
);
2014 if (*pixmap
== NULL
)
2016 DWORD err
= GetLastError ();
2017 Lisp_Object errcode
;
2018 /* All system errors are < 10000, so the following is safe. */
2019 XSETINT (errcode
, err
);
2020 image_error ("Unable to create bitmap, error code %d", errcode
, Qnil
);
2021 x_destroy_x_image (*ximg
);
2027 #endif /* HAVE_NTGUI */
2030 *pixmap
= ns_image_for_XPM (width
, height
, depth
);
2034 image_error ("Unable to allocate NSImage for XPM pixmap", Qnil
, Qnil
);
2043 /* Destroy XImage XIMG. Free XIMG->data. */
2046 x_destroy_x_image (XImagePtr ximg
)
2048 eassert (input_blocked_p ());
2051 #ifdef HAVE_X_WINDOWS
2054 XDestroyImage (ximg
);
2055 #endif /* HAVE_X_WINDOWS */
2057 /* Data will be freed by DestroyObject. */
2060 #endif /* HAVE_NTGUI */
2062 ns_release_object (ximg
);
2063 #endif /* HAVE_NS */
2068 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
2069 are width and height of both the image and pixmap. */
2072 x_put_x_image (struct frame
*f
, XImagePtr ximg
, Pixmap pixmap
, int width
, int height
)
2074 #ifdef HAVE_X_WINDOWS
2077 eassert (input_blocked_p ());
2078 gc
= XCreateGC (FRAME_X_DISPLAY (f
), pixmap
, 0, NULL
);
2079 XPutImage (FRAME_X_DISPLAY (f
), pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
2080 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
2081 #endif /* HAVE_X_WINDOWS */
2084 #if 0 /* I don't think this is necessary looking at where it is used. */
2085 HDC hdc
= get_frame_dc (f
);
2086 SetDIBits (hdc
, pixmap
, 0, height
, ximg
->data
, &(ximg
->info
), DIB_RGB_COLORS
);
2087 release_frame_dc (f
, hdc
);
2089 #endif /* HAVE_NTGUI */
2092 eassert (ximg
== pixmap
);
2093 ns_retain_object (ximg
);
2098 /***********************************************************************
2100 ***********************************************************************/
2102 /* Find image file FILE. Look in data-directory/images, then
2103 x-bitmap-file-path. Value is the encoded full name of the file
2104 found, or nil if not found. */
2107 x_find_image_file (Lisp_Object file
)
2109 Lisp_Object file_found
, search_path
;
2112 /* TODO I think this should use something like image-load-path
2113 instead. Unfortunately, that can contain non-string elements. */
2114 search_path
= Fcons (Fexpand_file_name (build_string ("images"),
2116 Vx_bitmap_file_path
);
2118 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
2119 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
2125 file_found
= ENCODE_FILE (file_found
);
2133 /* Read FILE into memory. Value is a pointer to a buffer allocated
2134 with xmalloc holding FILE's contents. Value is null if an error
2135 occurred. *SIZE is set to the size of the file. */
2137 static unsigned char *
2138 slurp_file (char *file
, ptrdiff_t *size
)
2140 FILE *fp
= fopen (file
, "rb");
2141 unsigned char *buf
= NULL
;
2144 if (fp
&& fstat (fileno (fp
), &st
) == 0
2145 && 0 <= st
.st_size
&& st
.st_size
<= min (PTRDIFF_MAX
, SIZE_MAX
)
2146 && (buf
= xmalloc (st
.st_size
),
2147 fread (buf
, 1, st
.st_size
, fp
) == st
.st_size
))
2168 /***********************************************************************
2170 ***********************************************************************/
2172 static bool xbm_load (struct frame
*f
, struct image
*img
);
2173 static bool xbm_image_p (Lisp_Object object
);
2174 static bool xbm_file_p (Lisp_Object
);
2177 /* Indices of image specification fields in xbm_format, below. */
2179 enum xbm_keyword_index
2197 /* Vector of image_keyword structures describing the format
2198 of valid XBM image specifications. */
2200 static const struct image_keyword xbm_format
[XBM_LAST
] =
2202 {":type", IMAGE_SYMBOL_VALUE
, 1},
2203 {":file", IMAGE_STRING_VALUE
, 0},
2204 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2205 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2206 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2207 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
2208 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
2209 {":ascent", IMAGE_ASCENT_VALUE
, 0},
2210 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
2211 {":relief", IMAGE_INTEGER_VALUE
, 0},
2212 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2213 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2214 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
2217 /* Structure describing the image type XBM. */
2219 static struct image_type xbm_type
=
2229 /* Tokens returned from xbm_scan. */
2238 /* Return true if OBJECT is a valid XBM-type image specification.
2239 A valid specification is a list starting with the symbol `image'
2240 The rest of the list is a property list which must contain an
2243 If the specification specifies a file to load, it must contain
2244 an entry `:file FILENAME' where FILENAME is a string.
2246 If the specification is for a bitmap loaded from memory it must
2247 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
2248 WIDTH and HEIGHT are integers > 0. DATA may be:
2250 1. a string large enough to hold the bitmap data, i.e. it must
2251 have a size >= (WIDTH + 7) / 8 * HEIGHT
2253 2. a bool-vector of size >= WIDTH * HEIGHT
2255 3. a vector of strings or bool-vectors, one for each line of the
2258 4. a string containing an in-memory XBM file. WIDTH and HEIGHT
2259 may not be specified in this case because they are defined in the
2262 Both the file and data forms may contain the additional entries
2263 `:background COLOR' and `:foreground COLOR'. If not present,
2264 foreground and background of the frame on which the image is
2265 displayed is used. */
2268 xbm_image_p (Lisp_Object object
)
2270 struct image_keyword kw
[XBM_LAST
];
2272 memcpy (kw
, xbm_format
, sizeof kw
);
2273 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
2276 eassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
2278 if (kw
[XBM_FILE
].count
)
2280 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
2283 else if (kw
[XBM_DATA
].count
&& xbm_file_p (kw
[XBM_DATA
].value
))
2285 /* In-memory XBM file. */
2286 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_FILE
].count
)
2294 /* Entries for `:width', `:height' and `:data' must be present. */
2295 if (!kw
[XBM_WIDTH
].count
2296 || !kw
[XBM_HEIGHT
].count
2297 || !kw
[XBM_DATA
].count
)
2300 data
= kw
[XBM_DATA
].value
;
2301 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
2302 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
2304 /* Check type of data, and width and height against contents of
2310 /* Number of elements of the vector must be >= height. */
2311 if (ASIZE (data
) < height
)
2314 /* Each string or bool-vector in data must be large enough
2315 for one line of the image. */
2316 for (i
= 0; i
< height
; ++i
)
2318 Lisp_Object elt
= AREF (data
, i
);
2323 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
2326 else if (BOOL_VECTOR_P (elt
))
2328 if (XBOOL_VECTOR (elt
)->size
< width
)
2335 else if (STRINGP (data
))
2338 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
2341 else if (BOOL_VECTOR_P (data
))
2343 if (XBOOL_VECTOR (data
)->size
/ height
< width
)
2354 /* Scan a bitmap file. FP is the stream to read from. Value is
2355 either an enumerator from enum xbm_token, or a character for a
2356 single-character token, or 0 at end of file. If scanning an
2357 identifier, store the lexeme of the identifier in SVAL. If
2358 scanning a number, store its value in *IVAL. */
2361 xbm_scan (unsigned char **s
, unsigned char *end
, char *sval
, int *ival
)
2367 /* Skip white space. */
2368 while (*s
< end
&& (c
= *(*s
)++, c_isspace (c
)))
2373 else if (c_isdigit (c
))
2375 int value
= 0, digit
;
2377 if (c
== '0' && *s
< end
)
2380 if (c
== 'x' || c
== 'X')
2387 else if (c
>= 'a' && c
<= 'f')
2388 digit
= c
- 'a' + 10;
2389 else if (c
>= 'A' && c
<= 'F')
2390 digit
= c
- 'A' + 10;
2393 value
= 16 * value
+ digit
;
2396 else if (c_isdigit (c
))
2400 && (c
= *(*s
)++, c_isdigit (c
)))
2401 value
= 8 * value
+ c
- '0';
2408 && (c
= *(*s
)++, c_isdigit (c
)))
2409 value
= 10 * value
+ c
- '0';
2417 else if (c_isalpha (c
) || c
== '_')
2421 && (c
= *(*s
)++, (c_isalnum (c
) || c
== '_')))
2428 else if (c
== '/' && **s
== '*')
2430 /* C-style comment. */
2432 while (**s
&& (**s
!= '*' || *(*s
+ 1) != '/'))
2446 /* Create a Windows bitmap from X bitmap data. */
2448 w32_create_pixmap_from_bitmap_data (int width
, int height
, char *data
)
2450 static unsigned char swap_nibble
[16]
2451 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
2452 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
2453 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
2454 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
2456 unsigned char *bits
, *p
;
2459 w1
= (width
+ 7) / 8; /* nb of 8bits elt in X bitmap */
2460 w2
= ((width
+ 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
2461 bits
= alloca (height
* w2
);
2462 memset (bits
, 0, height
* w2
);
2463 for (i
= 0; i
< height
; i
++)
2466 for (j
= 0; j
< w1
; j
++)
2468 /* Bitswap XBM bytes to match how Windows does things. */
2469 unsigned char c
= *data
++;
2470 *p
++ = (unsigned char)((swap_nibble
[c
& 0xf] << 4)
2471 | (swap_nibble
[(c
>>4) & 0xf]));
2474 bmp
= CreateBitmap (width
, height
, 1, 1, (char *) bits
);
2480 convert_mono_to_color_image (struct frame
*f
, struct image
*img
,
2481 COLORREF foreground
, COLORREF background
)
2483 HDC hdc
, old_img_dc
, new_img_dc
;
2484 HGDIOBJ old_prev
, new_prev
;
2487 hdc
= get_frame_dc (f
);
2488 old_img_dc
= CreateCompatibleDC (hdc
);
2489 new_img_dc
= CreateCompatibleDC (hdc
);
2490 new_pixmap
= CreateCompatibleBitmap (hdc
, img
->width
, img
->height
);
2491 release_frame_dc (f
, hdc
);
2492 old_prev
= SelectObject (old_img_dc
, img
->pixmap
);
2493 new_prev
= SelectObject (new_img_dc
, new_pixmap
);
2494 /* Windows convention for mono bitmaps is black = background,
2495 white = foreground. */
2496 SetTextColor (new_img_dc
, background
);
2497 SetBkColor (new_img_dc
, foreground
);
2499 BitBlt (new_img_dc
, 0, 0, img
->width
, img
->height
, old_img_dc
,
2502 SelectObject (old_img_dc
, old_prev
);
2503 SelectObject (new_img_dc
, new_prev
);
2504 DeleteDC (old_img_dc
);
2505 DeleteDC (new_img_dc
);
2506 DeleteObject (img
->pixmap
);
2507 if (new_pixmap
== 0)
2508 fprintf (stderr
, "Failed to convert image to color.\n");
2510 img
->pixmap
= new_pixmap
;
2513 #define XBM_BIT_SHUFFLE(b) (~(b))
2517 #define XBM_BIT_SHUFFLE(b) (b)
2519 #endif /* HAVE_NTGUI */
2523 Create_Pixmap_From_Bitmap_Data (struct frame
*f
, struct image
*img
, char *data
,
2524 RGB_PIXEL_COLOR fg
, RGB_PIXEL_COLOR bg
,
2525 bool non_default_colors
)
2529 = w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
, data
);
2531 /* If colors were specified, transfer the bitmap to a color one. */
2532 if (non_default_colors
)
2533 convert_mono_to_color_image (f
, img
, fg
, bg
);
2535 #elif defined (HAVE_NS)
2536 img
->pixmap
= ns_image_from_XBM (data
, img
->width
, img
->height
);
2540 (x_check_image_size (0, img
->width
, img
->height
)
2541 ? XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
2544 img
->width
, img
->height
,
2546 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)))
2548 #endif /* !HAVE_NTGUI && !HAVE_NS */
2553 /* Replacement for XReadBitmapFileData which isn't available under old
2554 X versions. CONTENTS is a pointer to a buffer to parse; END is the
2555 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
2556 the image. Return in *DATA the bitmap data allocated with xmalloc.
2557 Value is true if successful. DATA null means just test if
2558 CONTENTS looks like an in-memory XBM file. If INHIBIT_IMAGE_ERROR,
2559 inhibit the call to image_error when the image size is invalid (the
2560 bitmap remains unread). */
2563 xbm_read_bitmap_data (struct frame
*f
, unsigned char *contents
, unsigned char *end
,
2564 int *width
, int *height
, char **data
,
2565 bool inhibit_image_error
)
2567 unsigned char *s
= contents
;
2568 char buffer
[BUFSIZ
];
2571 int bytes_per_line
, i
, nbytes
;
2577 LA1 = xbm_scan (&s, end, buffer, &value)
2579 #define expect(TOKEN) \
2580 if (LA1 != (TOKEN)) \
2585 #define expect_ident(IDENT) \
2586 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
2591 *width
= *height
= -1;
2594 LA1
= xbm_scan (&s
, end
, buffer
, &value
);
2596 /* Parse defines for width, height and hot-spots. */
2600 expect_ident ("define");
2601 expect (XBM_TK_IDENT
);
2603 if (LA1
== XBM_TK_NUMBER
)
2605 char *q
= strrchr (buffer
, '_');
2606 q
= q
? q
+ 1 : buffer
;
2607 if (strcmp (q
, "width") == 0)
2609 else if (strcmp (q
, "height") == 0)
2612 expect (XBM_TK_NUMBER
);
2615 if (!check_image_size (f
, *width
, *height
))
2617 if (!inhibit_image_error
)
2618 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
2621 else if (data
== NULL
)
2624 /* Parse bits. Must start with `static'. */
2625 expect_ident ("static");
2626 if (LA1
== XBM_TK_IDENT
)
2628 if (strcmp (buffer
, "unsigned") == 0)
2631 expect_ident ("char");
2633 else if (strcmp (buffer
, "short") == 0)
2637 if (*width
% 16 && *width
% 16 < 9)
2640 else if (strcmp (buffer
, "char") == 0)
2648 expect (XBM_TK_IDENT
);
2654 if (! x_check_image_size (0, *width
, *height
))
2656 if (!inhibit_image_error
)
2657 image_error ("Image too large (%dx%d)",
2658 make_number (*width
), make_number (*height
));
2661 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
2662 nbytes
= bytes_per_line
* *height
;
2663 p
= *data
= xmalloc (nbytes
);
2667 for (i
= 0; i
< nbytes
; i
+= 2)
2670 expect (XBM_TK_NUMBER
);
2672 *p
++ = XBM_BIT_SHUFFLE (val
);
2673 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
2674 *p
++ = XBM_BIT_SHUFFLE (value
>> 8);
2676 if (LA1
== ',' || LA1
== '}')
2684 for (i
= 0; i
< nbytes
; ++i
)
2687 expect (XBM_TK_NUMBER
);
2689 *p
++ = XBM_BIT_SHUFFLE (val
);
2691 if (LA1
== ',' || LA1
== '}')
2716 /* Load XBM image IMG which will be displayed on frame F from buffer
2717 CONTENTS. END is the end of the buffer. Value is true if
2721 xbm_load_image (struct frame
*f
, struct image
*img
, unsigned char *contents
,
2728 rc
= xbm_read_bitmap_data (f
, contents
, end
, &img
->width
, &img
->height
,
2732 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2733 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2734 bool non_default_colors
= 0;
2737 eassert (img
->width
> 0 && img
->height
> 0);
2739 /* Get foreground and background colors, maybe allocate colors. */
2740 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
2743 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
2744 non_default_colors
= 1;
2746 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
2749 background
= x_alloc_image_color (f
, img
, value
, background
);
2750 img
->background
= background
;
2751 img
->background_valid
= 1;
2752 non_default_colors
= 1;
2755 Create_Pixmap_From_Bitmap_Data (f
, img
, data
,
2756 foreground
, background
,
2757 non_default_colors
);
2760 if (img
->pixmap
== NO_PIXMAP
)
2762 x_clear_image (f
, img
);
2763 image_error ("Unable to create X pixmap for `%s'", img
->spec
, Qnil
);
2769 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
2775 /* Value is true if DATA looks like an in-memory XBM file. */
2778 xbm_file_p (Lisp_Object data
)
2781 return (STRINGP (data
)
2782 && xbm_read_bitmap_data (NULL
, SDATA (data
),
2783 (SDATA (data
) + SBYTES (data
)),
2788 /* Fill image IMG which is used on frame F with pixmap data. Value is
2789 true if successful. */
2792 xbm_load (struct frame
*f
, struct image
*img
)
2795 Lisp_Object file_name
;
2797 eassert (xbm_image_p (img
->spec
));
2799 /* If IMG->spec specifies a file name, create a non-file spec from it. */
2800 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
2801 if (STRINGP (file_name
))
2804 unsigned char *contents
;
2807 file
= x_find_image_file (file_name
);
2808 if (!STRINGP (file
))
2810 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
2814 contents
= slurp_file (SSDATA (file
), &size
);
2815 if (contents
== NULL
)
2817 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
2821 success_p
= xbm_load_image (f
, img
, contents
, contents
+ size
);
2826 struct image_keyword fmt
[XBM_LAST
];
2828 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2829 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2830 bool non_default_colors
= 0;
2833 bool in_memory_file_p
= 0;
2835 /* See if data looks like an in-memory XBM file. */
2836 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
2837 in_memory_file_p
= xbm_file_p (data
);
2839 /* Parse the image specification. */
2840 memcpy (fmt
, xbm_format
, sizeof fmt
);
2841 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
2844 /* Get specified width, and height. */
2845 if (!in_memory_file_p
)
2847 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
2848 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
2849 eassert (img
->width
> 0 && img
->height
> 0);
2850 if (!check_image_size (f
, img
->width
, img
->height
))
2852 image_error ("Invalid image size (see `max-image-size')",
2858 /* Get foreground and background colors, maybe allocate colors. */
2859 if (fmt
[XBM_FOREGROUND
].count
2860 && STRINGP (fmt
[XBM_FOREGROUND
].value
))
2862 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
2864 non_default_colors
= 1;
2867 if (fmt
[XBM_BACKGROUND
].count
2868 && STRINGP (fmt
[XBM_BACKGROUND
].value
))
2870 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
2872 non_default_colors
= 1;
2875 if (in_memory_file_p
)
2876 success_p
= xbm_load_image (f
, img
, SDATA (data
),
2885 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
2887 p
= bits
= alloca (nbytes
* img
->height
);
2888 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
2890 Lisp_Object line
= AREF (data
, i
);
2892 memcpy (p
, SDATA (line
), nbytes
);
2894 memcpy (p
, XBOOL_VECTOR (line
)->data
, nbytes
);
2897 else if (STRINGP (data
))
2898 bits
= SSDATA (data
);
2900 bits
= (char *) XBOOL_VECTOR (data
)->data
;
2906 /* Windows mono bitmaps are reversed compared with X. */
2907 invertedBits
= bits
;
2908 nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
2910 bits
= alloca (nbytes
);
2911 for (i
= 0; i
< nbytes
; i
++)
2912 bits
[i
] = XBM_BIT_SHUFFLE (invertedBits
[i
]);
2915 /* Create the pixmap. */
2917 if (x_check_image_size (0, img
->width
, img
->height
))
2918 Create_Pixmap_From_Bitmap_Data (f
, img
, bits
,
2919 foreground
, background
,
2920 non_default_colors
);
2922 img
->pixmap
= NO_PIXMAP
;
2928 image_error ("Unable to create pixmap for XBM image `%s'",
2930 x_clear_image (f
, img
);
2940 /***********************************************************************
2942 ***********************************************************************/
2944 #if defined (HAVE_XPM) || defined (HAVE_NS)
2946 static bool xpm_image_p (Lisp_Object object
);
2947 static bool xpm_load (struct frame
*f
, struct image
*img
);
2949 #endif /* HAVE_XPM || HAVE_NS */
2953 /* Indicate to xpm.h that we don't have Xlib. */
2955 /* simx.h in xpm defines XColor and XImage differently than Emacs. */
2956 /* It also defines Display the same way as Emacs, but gcc 3.3 still barfs. */
2957 #define XColor xpm_XColor
2958 #define XImage xpm_XImage
2959 #define Display xpm_Display
2960 #define PIXEL_ALREADY_TYPEDEFED
2961 #include "X11/xpm.h"
2966 #undef PIXEL_ALREADY_TYPEDEFED
2968 #include "X11/xpm.h"
2969 #endif /* HAVE_NTGUI */
2970 #endif /* HAVE_XPM */
2972 #if defined (HAVE_XPM) || defined (HAVE_NS)
2973 /* The symbol `xpm' identifying XPM-format images. */
2975 static Lisp_Object Qxpm
;
2977 /* Indices of image specification fields in xpm_format, below. */
2979 enum xpm_keyword_index
2995 /* Vector of image_keyword structures describing the format
2996 of valid XPM image specifications. */
2998 static const struct image_keyword xpm_format
[XPM_LAST
] =
3000 {":type", IMAGE_SYMBOL_VALUE
, 1},
3001 {":file", IMAGE_STRING_VALUE
, 0},
3002 {":data", IMAGE_STRING_VALUE
, 0},
3003 {":ascent", IMAGE_ASCENT_VALUE
, 0},
3004 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
3005 {":relief", IMAGE_INTEGER_VALUE
, 0},
3006 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3007 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3008 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3009 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3010 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
3013 #if defined HAVE_NTGUI && defined WINDOWSNT
3014 static bool init_xpm_functions (void);
3016 #define init_xpm_functions NULL
3019 /* Structure describing the image type XPM. */
3021 static struct image_type xpm_type
=
3031 #ifdef HAVE_X_WINDOWS
3033 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
3034 functions for allocating image colors. Our own functions handle
3035 color allocation failures more gracefully than the ones on the XPM
3038 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
3039 #define ALLOC_XPM_COLORS
3041 #endif /* HAVE_X_WINDOWS */
3043 #ifdef ALLOC_XPM_COLORS
3045 static struct xpm_cached_color
*xpm_cache_color (struct frame
*, char *,
3048 /* An entry in a hash table used to cache color definitions of named
3049 colors. This cache is necessary to speed up XPM image loading in
3050 case we do color allocations ourselves. Without it, we would need
3051 a call to XParseColor per pixel in the image. */
3053 struct xpm_cached_color
3055 /* Next in collision chain. */
3056 struct xpm_cached_color
*next
;
3058 /* Color definition (RGB and pixel color). */
3062 char name
[FLEXIBLE_ARRAY_MEMBER
];
3065 /* The hash table used for the color cache, and its bucket vector
3068 #define XPM_COLOR_CACHE_BUCKETS 1001
3069 static struct xpm_cached_color
**xpm_color_cache
;
3071 /* Initialize the color cache. */
3074 xpm_init_color_cache (struct frame
*f
, XpmAttributes
*attrs
)
3076 size_t nbytes
= XPM_COLOR_CACHE_BUCKETS
* sizeof *xpm_color_cache
;
3077 xpm_color_cache
= xzalloc (nbytes
);
3078 init_color_table ();
3080 if (attrs
->valuemask
& XpmColorSymbols
)
3085 for (i
= 0; i
< attrs
->numsymbols
; ++i
)
3086 if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
3087 attrs
->colorsymbols
[i
].value
, &color
))
3089 color
.pixel
= lookup_rgb_color (f
, color
.red
, color
.green
,
3091 xpm_cache_color (f
, attrs
->colorsymbols
[i
].name
, &color
, -1);
3096 /* Free the color cache. */
3099 xpm_free_color_cache (void)
3101 struct xpm_cached_color
*p
, *next
;
3104 for (i
= 0; i
< XPM_COLOR_CACHE_BUCKETS
; ++i
)
3105 for (p
= xpm_color_cache
[i
]; p
; p
= next
)
3111 xfree (xpm_color_cache
);
3112 xpm_color_cache
= NULL
;
3113 free_color_table ();
3116 /* Return the bucket index for color named COLOR_NAME in the color
3120 xpm_color_bucket (char *color_name
)
3122 EMACS_UINT hash
= hash_string (color_name
, strlen (color_name
));
3123 return hash
% XPM_COLOR_CACHE_BUCKETS
;
3127 /* On frame F, cache values COLOR for color with name COLOR_NAME.
3128 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
3131 static struct xpm_cached_color
*
3132 xpm_cache_color (struct frame
*f
, char *color_name
, XColor
*color
, int bucket
)
3135 struct xpm_cached_color
*p
;
3138 bucket
= xpm_color_bucket (color_name
);
3140 nbytes
= offsetof (struct xpm_cached_color
, name
) + strlen (color_name
) + 1;
3141 p
= xmalloc (nbytes
);
3142 strcpy (p
->name
, color_name
);
3144 p
->next
= xpm_color_cache
[bucket
];
3145 xpm_color_cache
[bucket
] = p
;
3149 /* Look up color COLOR_NAME for frame F in the color cache. If found,
3150 return the cached definition in *COLOR. Otherwise, make a new
3151 entry in the cache and allocate the color. Value is false if color
3152 allocation failed. */
3155 xpm_lookup_color (struct frame
*f
, char *color_name
, XColor
*color
)
3157 struct xpm_cached_color
*p
;
3158 int h
= xpm_color_bucket (color_name
);
3160 for (p
= xpm_color_cache
[h
]; p
; p
= p
->next
)
3161 if (strcmp (p
->name
, color_name
) == 0)
3166 else if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
3169 color
->pixel
= lookup_rgb_color (f
, color
->red
, color
->green
,
3171 p
= xpm_cache_color (f
, color_name
, color
, h
);
3173 /* You get `opaque' at least from ImageMagick converting pbm to xpm
3174 with transparency, and it's useful. */
3175 else if (strcmp ("opaque", color_name
) == 0)
3177 memset (color
, 0, sizeof (XColor
)); /* Is this necessary/correct? */
3178 color
->pixel
= FRAME_FOREGROUND_PIXEL (f
);
3179 p
= xpm_cache_color (f
, color_name
, color
, h
);
3186 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
3187 CLOSURE is a pointer to the frame on which we allocate the
3188 color. Return in *COLOR the allocated color. Value is non-zero
3192 xpm_alloc_color (Display
*dpy
, Colormap cmap
, char *color_name
, XColor
*color
,
3195 return xpm_lookup_color ((struct frame
*) closure
, color_name
, color
);
3199 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
3200 is a pointer to the frame on which we allocate the color. Value is
3201 non-zero if successful. */
3204 xpm_free_colors (Display
*dpy
, Colormap cmap
, Pixel
*pixels
, int npixels
, void *closure
)
3209 #endif /* ALLOC_XPM_COLORS */
3214 /* XPM library details. */
3216 DEF_IMGLIB_FN (void, XpmFreeAttributes
, (XpmAttributes
*));
3217 DEF_IMGLIB_FN (int, XpmCreateImageFromBuffer
, (Display
*, char *, xpm_XImage
**,
3218 xpm_XImage
**, XpmAttributes
*));
3219 DEF_IMGLIB_FN (int, XpmReadFileToImage
, (Display
*, char *, xpm_XImage
**,
3220 xpm_XImage
**, XpmAttributes
*));
3221 DEF_IMGLIB_FN (void, XImageFree
, (xpm_XImage
*));
3224 init_xpm_functions (void)
3228 if (!(library
= w32_delayed_load (Qxpm
)))
3231 LOAD_IMGLIB_FN (library
, XpmFreeAttributes
);
3232 LOAD_IMGLIB_FN (library
, XpmCreateImageFromBuffer
);
3233 LOAD_IMGLIB_FN (library
, XpmReadFileToImage
);
3234 LOAD_IMGLIB_FN (library
, XImageFree
);
3238 #endif /* WINDOWSNT */
3240 #if defined HAVE_NTGUI && !defined WINDOWSNT
3241 /* Glue for code below */
3242 #define fn_XpmReadFileToImage XpmReadFileToImage
3243 #define fn_XpmCreateImageFromBuffer XpmCreateImageFromBuffer
3244 #define fn_XImageFree XImageFree
3245 #define fn_XpmFreeAttributes XpmFreeAttributes
3246 #endif /* HAVE_NTGUI && !WINDOWSNT */
3248 /* Value is true if COLOR_SYMBOLS is a valid color symbols list
3249 for XPM images. Such a list must consist of conses whose car and
3253 xpm_valid_color_symbols_p (Lisp_Object color_symbols
)
3255 while (CONSP (color_symbols
))
3257 Lisp_Object sym
= XCAR (color_symbols
);
3259 || !STRINGP (XCAR (sym
))
3260 || !STRINGP (XCDR (sym
)))
3262 color_symbols
= XCDR (color_symbols
);
3265 return NILP (color_symbols
);
3269 /* Value is true if OBJECT is a valid XPM image specification. */
3272 xpm_image_p (Lisp_Object object
)
3274 struct image_keyword fmt
[XPM_LAST
];
3275 memcpy (fmt
, xpm_format
, sizeof fmt
);
3276 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
3277 /* Either `:file' or `:data' must be present. */
3278 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
3279 /* Either no `:color-symbols' or it's a list of conses
3280 whose car and cdr are strings. */
3281 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
3282 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
)));
3285 #endif /* HAVE_XPM || HAVE_NS */
3287 #if defined HAVE_XPM && defined HAVE_X_WINDOWS && !defined USE_GTK
3289 x_create_bitmap_from_xpm_data (struct frame
*f
, const char **bits
)
3291 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3294 XpmAttributes attrs
;
3295 Pixmap bitmap
, mask
;
3297 memset (&attrs
, 0, sizeof attrs
);
3299 attrs
.visual
= FRAME_X_VISUAL (f
);
3300 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3301 attrs
.valuemask
|= XpmVisual
;
3302 attrs
.valuemask
|= XpmColormap
;
3304 rc
= XpmCreatePixmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3305 (char **) bits
, &bitmap
, &mask
, &attrs
);
3306 if (rc
!= XpmSuccess
)
3308 XpmFreeAttributes (&attrs
);
3312 id
= x_allocate_bitmap_record (f
);
3313 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
3314 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
3315 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
3316 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
3317 dpyinfo
->bitmaps
[id
- 1].height
= attrs
.height
;
3318 dpyinfo
->bitmaps
[id
- 1].width
= attrs
.width
;
3319 dpyinfo
->bitmaps
[id
- 1].depth
= attrs
.depth
;
3320 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
3322 XpmFreeAttributes (&attrs
);
3325 #endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */
3327 /* Load image IMG which will be displayed on frame F. Value is
3328 true if successful. */
3333 xpm_load (struct frame
*f
, struct image
*img
)
3336 XpmAttributes attrs
;
3337 Lisp_Object specified_file
, color_symbols
;
3340 xpm_XImage
* xpm_image
= NULL
, * xpm_mask
= NULL
;
3341 #endif /* HAVE_NTGUI */
3343 /* Configure the XPM lib. Use the visual of frame F. Allocate
3344 close colors. Return colors allocated. */
3345 memset (&attrs
, 0, sizeof attrs
);
3348 attrs
.visual
= FRAME_X_VISUAL (f
);
3349 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3350 attrs
.valuemask
|= XpmVisual
;
3351 attrs
.valuemask
|= XpmColormap
;
3352 #endif /* HAVE_NTGUI */
3354 #ifdef ALLOC_XPM_COLORS
3355 /* Allocate colors with our own functions which handle
3356 failing color allocation more gracefully. */
3357 attrs
.color_closure
= f
;
3358 attrs
.alloc_color
= xpm_alloc_color
;
3359 attrs
.free_colors
= xpm_free_colors
;
3360 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
3361 #else /* not ALLOC_XPM_COLORS */
3362 /* Let the XPM lib allocate colors. */
3363 attrs
.valuemask
|= XpmReturnAllocPixels
;
3364 #ifdef XpmAllocCloseColors
3365 attrs
.alloc_close_colors
= 1;
3366 attrs
.valuemask
|= XpmAllocCloseColors
;
3367 #else /* not XpmAllocCloseColors */
3368 attrs
.closeness
= 600;
3369 attrs
.valuemask
|= XpmCloseness
;
3370 #endif /* not XpmAllocCloseColors */
3371 #endif /* ALLOC_XPM_COLORS */
3373 /* If image specification contains symbolic color definitions, add
3374 these to `attrs'. */
3375 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
3376 if (CONSP (color_symbols
))
3379 XpmColorSymbol
*xpm_syms
;
3382 attrs
.valuemask
|= XpmColorSymbols
;
3384 /* Count number of symbols. */
3385 attrs
.numsymbols
= 0;
3386 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
3389 /* Allocate an XpmColorSymbol array. */
3390 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
3391 xpm_syms
= alloca (size
);
3392 memset (xpm_syms
, 0, size
);
3393 attrs
.colorsymbols
= xpm_syms
;
3395 /* Fill the color symbol array. */
3396 for (tail
= color_symbols
, i
= 0;
3398 ++i
, tail
= XCDR (tail
))
3402 char *empty_string
= (char *) "";
3404 if (!CONSP (XCAR (tail
)))
3406 xpm_syms
[i
].name
= empty_string
;
3407 xpm_syms
[i
].value
= empty_string
;
3410 name
= XCAR (XCAR (tail
));
3411 color
= XCDR (XCAR (tail
));
3414 xpm_syms
[i
].name
= alloca (SCHARS (name
) + 1);
3415 strcpy (xpm_syms
[i
].name
, SSDATA (name
));
3418 xpm_syms
[i
].name
= empty_string
;
3419 if (STRINGP (color
))
3421 xpm_syms
[i
].value
= alloca (SCHARS (color
) + 1);
3422 strcpy (xpm_syms
[i
].value
, SSDATA (color
));
3425 xpm_syms
[i
].value
= empty_string
;
3429 /* Create a pixmap for the image, either from a file, or from a
3430 string buffer containing data in the same format as an XPM file. */
3431 #ifdef ALLOC_XPM_COLORS
3432 xpm_init_color_cache (f
, &attrs
);
3435 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
3439 HDC frame_dc
= get_frame_dc (f
);
3440 hdc
= CreateCompatibleDC (frame_dc
);
3441 release_frame_dc (f
, frame_dc
);
3443 #endif /* HAVE_NTGUI */
3445 if (STRINGP (specified_file
))
3447 Lisp_Object file
= x_find_image_file (specified_file
);
3448 if (!STRINGP (file
))
3450 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
3451 #ifdef ALLOC_XPM_COLORS
3452 xpm_free_color_cache ();
3458 /* XpmReadFileToPixmap is not available in the Windows port of
3459 libxpm. But XpmReadFileToImage almost does what we want. */
3460 rc
= fn_XpmReadFileToImage (&hdc
, SDATA (file
),
3461 &xpm_image
, &xpm_mask
,
3464 rc
= XpmReadFileToPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3465 SSDATA (file
), &img
->pixmap
, &img
->mask
,
3467 #endif /* HAVE_NTGUI */
3471 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
3472 if (!STRINGP (buffer
))
3474 image_error ("Invalid image data `%s'", buffer
, Qnil
);
3475 #ifdef ALLOC_XPM_COLORS
3476 xpm_free_color_cache ();
3481 /* XpmCreatePixmapFromBuffer is not available in the Windows port
3482 of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
3483 rc
= fn_XpmCreateImageFromBuffer (&hdc
, SDATA (buffer
),
3484 &xpm_image
, &xpm_mask
,
3487 rc
= XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3489 &img
->pixmap
, &img
->mask
,
3491 #endif /* HAVE_NTGUI */
3494 if (rc
== XpmSuccess
)
3496 #if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS)
3497 img
->colors
= colors_in_color_table (&img
->ncolors
);
3498 #else /* not ALLOC_XPM_COLORS */
3502 /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
3503 plus some duplicate attributes. */
3504 if (xpm_image
&& xpm_image
->bitmap
)
3506 img
->pixmap
= xpm_image
->bitmap
;
3507 /* XImageFree in libXpm frees XImage struct without destroying
3508 the bitmap, which is what we want. */
3509 fn_XImageFree (xpm_image
);
3511 if (xpm_mask
&& xpm_mask
->bitmap
)
3513 /* The mask appears to be inverted compared with what we expect.
3514 TODO: invert our expectations. See other places where we
3515 have to invert bits because our idea of masks is backwards. */
3517 old_obj
= SelectObject (hdc
, xpm_mask
->bitmap
);
3519 PatBlt (hdc
, 0, 0, xpm_mask
->width
, xpm_mask
->height
, DSTINVERT
);
3520 SelectObject (hdc
, old_obj
);
3522 img
->mask
= xpm_mask
->bitmap
;
3523 fn_XImageFree (xpm_mask
);
3528 #endif /* HAVE_NTGUI */
3530 /* Remember allocated colors. */
3531 img
->colors
= xnmalloc (attrs
.nalloc_pixels
, sizeof *img
->colors
);
3532 img
->ncolors
= attrs
.nalloc_pixels
;
3533 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
3535 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
3536 #ifdef DEBUG_X_COLORS
3537 register_color (img
->colors
[i
]);
3540 #endif /* not ALLOC_XPM_COLORS */
3542 img
->width
= attrs
.width
;
3543 img
->height
= attrs
.height
;
3544 eassert (img
->width
> 0 && img
->height
> 0);
3546 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
3548 fn_XpmFreeAttributes (&attrs
);
3550 XpmFreeAttributes (&attrs
);
3551 #endif /* HAVE_NTGUI */
3557 #endif /* HAVE_NTGUI */
3562 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
3565 case XpmFileInvalid
:
3566 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
3570 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
3573 case XpmColorFailed
:
3574 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
3578 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
3583 #ifdef ALLOC_XPM_COLORS
3584 xpm_free_color_cache ();
3586 return rc
== XpmSuccess
;
3589 #endif /* HAVE_XPM */
3591 #if defined (HAVE_NS) && !defined (HAVE_XPM)
3593 /* XPM support functions for NS where libxpm is not available.
3594 Only XPM version 3 (without any extensions) is supported. */
3596 static void xpm_put_color_table_v (Lisp_Object
, const unsigned char *,
3598 static Lisp_Object
xpm_get_color_table_v (Lisp_Object
,
3599 const unsigned char *, int);
3600 static void xpm_put_color_table_h (Lisp_Object
, const unsigned char *,
3602 static Lisp_Object
xpm_get_color_table_h (Lisp_Object
,
3603 const unsigned char *, int);
3605 /* Tokens returned from xpm_scan. */
3614 /* Scan an XPM data and return a character (< 256) or a token defined
3615 by enum xpm_token above. *S and END are the start (inclusive) and
3616 the end (exclusive) addresses of the data, respectively. Advance
3617 *S while scanning. If token is either XPM_TK_IDENT or
3618 XPM_TK_STRING, *BEG and *LEN are set to the start address and the
3619 length of the corresponding token, respectively. */
3622 xpm_scan (const unsigned char **s
,
3623 const unsigned char *end
,
3624 const unsigned char **beg
,
3631 /* Skip white-space. */
3632 while (*s
< end
&& (c
= *(*s
)++, c_isspace (c
)))
3635 /* gnus-pointer.xpm uses '-' in its identifier.
3636 sb-dir-plus.xpm uses '+' in its identifier. */
3637 if (c_isalpha (c
) || c
== '_' || c
== '-' || c
== '+')
3641 && (c
= **s
, c_isalnum (c
)
3642 || c
== '_' || c
== '-' || c
== '+'))
3645 return XPM_TK_IDENT
;
3650 while (*s
< end
&& **s
!= '"')
3655 return XPM_TK_STRING
;
3659 if (*s
< end
&& **s
== '*')
3661 /* C-style comment. */
3665 while (*s
< end
&& *(*s
)++ != '*')
3668 while (*s
< end
&& **s
!= '/');
3682 /* Functions for color table lookup in XPM data. A key is a string
3683 specifying the color of each pixel in XPM data. A value is either
3684 an integer that specifies a pixel color, Qt that specifies
3685 transparency, or Qnil for the unspecified color. If the length of
3686 the key string is one, a vector is used as a table. Otherwise, a
3687 hash table is used. */
3690 xpm_make_color_table_v (void (**put_func
) (Lisp_Object
,
3691 const unsigned char *,
3694 Lisp_Object (**get_func
) (Lisp_Object
,
3695 const unsigned char *,
3698 *put_func
= xpm_put_color_table_v
;
3699 *get_func
= xpm_get_color_table_v
;
3700 return Fmake_vector (make_number (256), Qnil
);
3704 xpm_put_color_table_v (Lisp_Object color_table
,
3705 const unsigned char *chars_start
,
3709 ASET (color_table
, *chars_start
, color
);
3713 xpm_get_color_table_v (Lisp_Object color_table
,
3714 const unsigned char *chars_start
,
3717 return AREF (color_table
, *chars_start
);
3721 xpm_make_color_table_h (void (**put_func
) (Lisp_Object
,
3722 const unsigned char *,
3725 Lisp_Object (**get_func
) (Lisp_Object
,
3726 const unsigned char *,
3729 *put_func
= xpm_put_color_table_h
;
3730 *get_func
= xpm_get_color_table_h
;
3731 return make_hash_table (hashtest_equal
, make_number (DEFAULT_HASH_SIZE
),
3732 make_float (DEFAULT_REHASH_SIZE
),
3733 make_float (DEFAULT_REHASH_THRESHOLD
),
3738 xpm_put_color_table_h (Lisp_Object color_table
,
3739 const unsigned char *chars_start
,
3743 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
3744 EMACS_UINT hash_code
;
3745 Lisp_Object chars
= make_unibyte_string (chars_start
, chars_len
);
3747 hash_lookup (table
, chars
, &hash_code
);
3748 hash_put (table
, chars
, color
, hash_code
);
3752 xpm_get_color_table_h (Lisp_Object color_table
,
3753 const unsigned char *chars_start
,
3756 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
3758 hash_lookup (table
, make_unibyte_string (chars_start
, chars_len
), NULL
);
3760 return i
>= 0 ? HASH_VALUE (table
, i
) : Qnil
;
3763 enum xpm_color_key
{
3771 static const char xpm_color_key_strings
[][4] = {"s", "m", "g4", "g", "c"};
3774 xpm_str_to_color_key (const char *s
)
3779 i
< sizeof xpm_color_key_strings
/ sizeof xpm_color_key_strings
[0];
3781 if (strcmp (xpm_color_key_strings
[i
], s
) == 0)
3787 xpm_load_image (struct frame
*f
,
3789 const unsigned char *contents
,
3790 const unsigned char *end
)
3792 const unsigned char *s
= contents
, *beg
, *str
;
3793 unsigned char buffer
[BUFSIZ
];
3794 int width
, height
, x
, y
;
3795 int num_colors
, chars_per_pixel
;
3798 void (*put_color_table
) (Lisp_Object
, const unsigned char *, int, Lisp_Object
);
3799 Lisp_Object (*get_color_table
) (Lisp_Object
, const unsigned char *, int);
3800 Lisp_Object frame
, color_symbols
, color_table
;
3803 XImagePtr ximg
= NULL
, mask_img
= NULL
;
3806 LA1 = xpm_scan (&s, end, &beg, &len)
3808 #define expect(TOKEN) \
3809 if (LA1 != (TOKEN)) \
3814 #define expect_ident(IDENT) \
3815 if (LA1 == XPM_TK_IDENT \
3816 && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
3821 if (!(end
- s
>= 9 && memcmp (s
, "/* XPM */", 9) == 0))
3825 expect_ident ("static");
3826 expect_ident ("char");
3828 expect (XPM_TK_IDENT
);
3833 expect (XPM_TK_STRING
);
3836 memcpy (buffer
, beg
, len
);
3838 if (sscanf (buffer
, "%d %d %d %d", &width
, &height
,
3839 &num_colors
, &chars_per_pixel
) != 4
3840 || width
<= 0 || height
<= 0
3841 || num_colors
<= 0 || chars_per_pixel
<= 0)
3844 if (!check_image_size (f
, width
, height
))
3846 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
3850 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
3851 &ximg
, &img
->pixmap
)
3853 || !x_create_x_image_and_pixmap (f
, width
, height
, 1,
3854 &mask_img
, &img
->mask
)
3858 image_error ("Image too large", Qnil
, Qnil
);
3864 XSETFRAME (frame
, f
);
3865 if (!NILP (Fxw_display_color_p (frame
)))
3866 best_key
= XPM_COLOR_KEY_C
;
3867 else if (!NILP (Fx_display_grayscale_p (frame
)))
3868 best_key
= (XFASTINT (Fx_display_planes (frame
)) > 2
3869 ? XPM_COLOR_KEY_G
: XPM_COLOR_KEY_G4
);
3871 best_key
= XPM_COLOR_KEY_M
;
3873 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
3874 if (chars_per_pixel
== 1)
3875 color_table
= xpm_make_color_table_v (&put_color_table
,
3878 color_table
= xpm_make_color_table_h (&put_color_table
,
3881 while (num_colors
-- > 0)
3883 char *color
, *max_color
;
3884 int key
, next_key
, max_key
= 0;
3885 Lisp_Object symbol_color
= Qnil
, color_val
;
3888 expect (XPM_TK_STRING
);
3889 if (len
<= chars_per_pixel
|| len
>= BUFSIZ
+ chars_per_pixel
)
3891 memcpy (buffer
, beg
+ chars_per_pixel
, len
- chars_per_pixel
);
3892 buffer
[len
- chars_per_pixel
] = '\0';
3894 str
= strtok (buffer
, " \t");
3897 key
= xpm_str_to_color_key (str
);
3902 color
= strtok (NULL
, " \t");
3906 while ((str
= strtok (NULL
, " \t")) != NULL
)
3908 next_key
= xpm_str_to_color_key (str
);
3911 color
[strlen (color
)] = ' ';
3914 if (key
== XPM_COLOR_KEY_S
)
3916 if (NILP (symbol_color
))
3917 symbol_color
= build_string (color
);
3919 else if (max_key
< key
&& key
<= best_key
)
3929 if (!NILP (color_symbols
) && !NILP (symbol_color
))
3931 Lisp_Object specified_color
= Fassoc (symbol_color
, color_symbols
);
3933 if (CONSP (specified_color
) && STRINGP (XCDR (specified_color
)))
3935 if (xstrcasecmp (SSDATA (XCDR (specified_color
)), "None") == 0)
3937 else if (x_defined_color (f
, SSDATA (XCDR (specified_color
)),
3939 color_val
= make_number (cdef
.pixel
);
3942 if (NILP (color_val
) && max_key
> 0)
3944 if (xstrcasecmp (max_color
, "None") == 0)
3946 else if (x_defined_color (f
, max_color
, &cdef
, 0))
3947 color_val
= make_number (cdef
.pixel
);
3949 if (!NILP (color_val
))
3950 (*put_color_table
) (color_table
, beg
, chars_per_pixel
, color_val
);
3955 for (y
= 0; y
< height
; y
++)
3957 expect (XPM_TK_STRING
);
3959 if (len
< width
* chars_per_pixel
)
3961 for (x
= 0; x
< width
; x
++, str
+= chars_per_pixel
)
3963 Lisp_Object color_val
=
3964 (*get_color_table
) (color_table
, str
, chars_per_pixel
);
3966 XPutPixel (ximg
, x
, y
,
3967 (INTEGERP (color_val
) ? XINT (color_val
)
3968 : FRAME_FOREGROUND_PIXEL (f
)));
3970 XPutPixel (mask_img
, x
, y
,
3971 (!EQ (color_val
, Qt
) ? PIX_MASK_DRAW
3972 : (have_mask
= 1, PIX_MASK_RETAIN
)));
3974 if (EQ (color_val
, Qt
))
3975 ns_set_alpha (ximg
, x
, y
, 0);
3983 img
->height
= height
;
3985 /* Maybe fill in the background field while we have ximg handy. */
3986 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
3987 IMAGE_BACKGROUND (img
, f
, ximg
);
3989 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
3990 x_destroy_x_image (ximg
);
3994 /* Fill in the background_transparent field while we have the
3996 image_background_transparent (img
, f
, mask_img
);
3998 x_put_x_image (f
, mask_img
, img
->mask
, width
, height
);
3999 x_destroy_x_image (mask_img
);
4003 x_destroy_x_image (mask_img
);
4004 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4005 img
->mask
= NO_PIXMAP
;
4011 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
4012 x_destroy_x_image (ximg
);
4013 x_destroy_x_image (mask_img
);
4014 x_clear_image (f
, img
);
4023 xpm_load (struct frame
*f
,
4027 Lisp_Object file_name
;
4029 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4030 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
4031 if (STRINGP (file_name
))
4034 unsigned char *contents
;
4037 file
= x_find_image_file (file_name
);
4038 if (!STRINGP (file
))
4040 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
4044 contents
= slurp_file (SSDATA (file
), &size
);
4045 if (contents
== NULL
)
4047 image_error ("Error loading XPM image `%s'", img
->spec
, Qnil
);
4051 success_p
= xpm_load_image (f
, img
, contents
, contents
+ size
);
4058 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
4059 if (!STRINGP (data
))
4061 image_error ("Invalid image data `%s'", data
, Qnil
);
4064 success_p
= xpm_load_image (f
, img
, SDATA (data
),
4065 SDATA (data
) + SBYTES (data
));
4071 #endif /* HAVE_NS && !HAVE_XPM */
4075 /***********************************************************************
4077 ***********************************************************************/
4079 #ifdef COLOR_TABLE_SUPPORT
4081 /* An entry in the color table mapping an RGB color to a pixel color. */
4086 unsigned long pixel
;
4088 /* Next in color table collision list. */
4089 struct ct_color
*next
;
4092 /* The bucket vector size to use. Must be prime. */
4096 /* Value is a hash of the RGB color given by R, G, and B. */
4098 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
4100 /* The color hash table. */
4102 static struct ct_color
**ct_table
;
4104 /* Number of entries in the color table. */
4106 static int ct_colors_allocated
;
4109 ct_colors_allocated_max
=
4111 min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof (unsigned long))
4114 /* Initialize the color table. */
4117 init_color_table (void)
4119 int size
= CT_SIZE
* sizeof (*ct_table
);
4120 ct_table
= xzalloc (size
);
4121 ct_colors_allocated
= 0;
4125 /* Free memory associated with the color table. */
4128 free_color_table (void)
4131 struct ct_color
*p
, *next
;
4133 for (i
= 0; i
< CT_SIZE
; ++i
)
4134 for (p
= ct_table
[i
]; p
; p
= next
)
4145 /* Value is a pixel color for RGB color R, G, B on frame F. If an
4146 entry for that color already is in the color table, return the
4147 pixel color of that entry. Otherwise, allocate a new color for R,
4148 G, B, and make an entry in the color table. */
4150 static unsigned long
4151 lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
)
4153 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
4154 int i
= hash
% CT_SIZE
;
4156 Display_Info
*dpyinfo
;
4158 /* Handle TrueColor visuals specially, which improves performance by
4159 two orders of magnitude. Freeing colors on TrueColor visuals is
4160 a nop, and pixel colors specify RGB values directly. See also
4161 the Xlib spec, chapter 3.1. */
4162 dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
4163 if (dpyinfo
->red_bits
> 0)
4165 unsigned long pr
, pg
, pb
;
4167 /* Apply gamma-correction like normal color allocation does. */
4171 color
.red
= r
, color
.green
= g
, color
.blue
= b
;
4172 gamma_correct (f
, &color
);
4173 r
= color
.red
, g
= color
.green
, b
= color
.blue
;
4176 /* Scale down RGB values to the visual's bits per RGB, and shift
4177 them to the right position in the pixel color. Note that the
4178 original RGB values are 16-bit values, as usual in X. */
4179 pr
= (r
>> (16 - dpyinfo
->red_bits
)) << dpyinfo
->red_offset
;
4180 pg
= (g
>> (16 - dpyinfo
->green_bits
)) << dpyinfo
->green_offset
;
4181 pb
= (b
>> (16 - dpyinfo
->blue_bits
)) << dpyinfo
->blue_offset
;
4183 /* Assemble the pixel color. */
4184 return pr
| pg
| pb
;
4187 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4188 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
4194 #ifdef HAVE_X_WINDOWS
4202 if (ct_colors_allocated_max
<= ct_colors_allocated
)
4203 return FRAME_FOREGROUND_PIXEL (f
);
4205 #ifdef HAVE_X_WINDOWS
4210 cmap
= FRAME_X_COLORMAP (f
);
4211 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4214 ++ct_colors_allocated
;
4215 p
= xmalloc (sizeof *p
);
4219 p
->pixel
= color
.pixel
;
4220 p
->next
= ct_table
[i
];
4224 return FRAME_FOREGROUND_PIXEL (f
);
4228 color
= PALETTERGB (r
, g
, b
);
4230 color
= RGB_TO_ULONG (r
, g
, b
);
4231 #endif /* HAVE_NTGUI */
4232 ++ct_colors_allocated
;
4233 p
= xmalloc (sizeof *p
);
4238 p
->next
= ct_table
[i
];
4240 #endif /* HAVE_X_WINDOWS */
4248 /* Look up pixel color PIXEL which is used on frame F in the color
4249 table. If not already present, allocate it. Value is PIXEL. */
4251 static unsigned long
4252 lookup_pixel_color (struct frame
*f
, unsigned long pixel
)
4254 int i
= pixel
% CT_SIZE
;
4257 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4258 if (p
->pixel
== pixel
)
4267 if (ct_colors_allocated_max
<= ct_colors_allocated
)
4268 return FRAME_FOREGROUND_PIXEL (f
);
4270 #ifdef HAVE_X_WINDOWS
4271 cmap
= FRAME_X_COLORMAP (f
);
4272 color
.pixel
= pixel
;
4273 x_query_color (f
, &color
);
4274 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4277 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
4278 color
.pixel
= pixel
;
4279 XQueryColor (NULL
, cmap
, &color
);
4280 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4282 #endif /* HAVE_X_WINDOWS */
4286 ++ct_colors_allocated
;
4288 p
= xmalloc (sizeof *p
);
4293 p
->next
= ct_table
[i
];
4297 return FRAME_FOREGROUND_PIXEL (f
);
4303 /* Value is a vector of all pixel colors contained in the color table,
4304 allocated via xmalloc. Set *N to the number of colors. */
4306 static unsigned long *
4307 colors_in_color_table (int *n
)
4311 unsigned long *colors
;
4313 if (ct_colors_allocated
== 0)
4320 colors
= xmalloc (ct_colors_allocated
* sizeof *colors
);
4321 *n
= ct_colors_allocated
;
4323 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
4324 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4325 colors
[j
++] = p
->pixel
;
4331 #else /* COLOR_TABLE_SUPPORT */
4333 static unsigned long
4334 lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
)
4336 unsigned long pixel
;
4339 pixel
= PALETTERGB (r
>> 8, g
>> 8, b
>> 8);
4340 #endif /* HAVE_NTGUI */
4343 pixel
= RGB_TO_ULONG (r
>> 8, g
>> 8, b
>> 8);
4344 #endif /* HAVE_NS */
4349 init_color_table (void)
4352 #endif /* COLOR_TABLE_SUPPORT */
4355 /***********************************************************************
4357 ***********************************************************************/
4359 /* Edge detection matrices for different edge-detection
4362 static int emboss_matrix
[9] = {
4364 2, -1, 0, /* y - 1 */
4366 0, 1, -2 /* y + 1 */
4369 static int laplace_matrix
[9] = {
4371 1, 0, 0, /* y - 1 */
4373 0, 0, -1 /* y + 1 */
4376 /* Value is the intensity of the color whose red/green/blue values
4379 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
4382 /* On frame F, return an array of XColor structures describing image
4383 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
4384 means also fill the red/green/blue members of the XColor
4385 structures. Value is a pointer to the array of XColors structures,
4386 allocated with xmalloc; it must be freed by the caller. */
4389 x_to_xcolors (struct frame
*f
, struct image
*img
, bool rgb_p
)
4393 XImagePtr_or_DC ximg
;
4397 #endif /* HAVE_NTGUI */
4399 if (min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *colors
/ img
->width
< img
->height
)
4400 memory_full (SIZE_MAX
);
4401 colors
= xmalloc (sizeof *colors
* img
->width
* img
->height
);
4404 /* Get the X image IMG->pixmap. */
4405 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
4406 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
4408 /* Load the image into a memory device context. */
4409 hdc
= get_frame_dc (f
);
4410 ximg
= CreateCompatibleDC (hdc
);
4411 release_frame_dc (f
, hdc
);
4412 prev
= SelectObject (ximg
, img
->pixmap
);
4413 #endif /* HAVE_NTGUI */
4415 /* Fill the `pixel' members of the XColor array. I wished there
4416 were an easy and portable way to circumvent XGetPixel. */
4418 for (y
= 0; y
< img
->height
; ++y
)
4420 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
4422 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4423 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4425 x_query_colors (f
, row
, img
->width
);
4429 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4431 /* W32_TODO: palette support needed here? */
4432 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4435 p
->red
= RED16_FROM_ULONG (p
->pixel
);
4436 p
->green
= GREEN16_FROM_ULONG (p
->pixel
);
4437 p
->blue
= BLUE16_FROM_ULONG (p
->pixel
);
4440 #endif /* HAVE_X_WINDOWS */
4443 Destroy_Image (ximg
, prev
);
4450 /* Put a pixel of COLOR at position X, Y in XIMG. XIMG must have been
4451 created with CreateDIBSection, with the pointer to the bit values
4452 stored in ximg->data. */
4455 XPutPixel (XImagePtr ximg
, int x
, int y
, COLORREF color
)
4457 int width
= ximg
->info
.bmiHeader
.biWidth
;
4458 unsigned char * pixel
;
4460 /* True color images. */
4461 if (ximg
->info
.bmiHeader
.biBitCount
== 24)
4463 int rowbytes
= width
* 3;
4464 /* Ensure scanlines are aligned on 4 byte boundaries. */
4466 rowbytes
+= 4 - (rowbytes
% 4);
4468 pixel
= ximg
->data
+ y
* rowbytes
+ x
* 3;
4469 /* Windows bitmaps are in BGR order. */
4470 *pixel
= GetBValue (color
);
4471 *(pixel
+ 1) = GetGValue (color
);
4472 *(pixel
+ 2) = GetRValue (color
);
4474 /* Monochrome images. */
4475 else if (ximg
->info
.bmiHeader
.biBitCount
== 1)
4477 int rowbytes
= width
/ 8;
4478 /* Ensure scanlines are aligned on 4 byte boundaries. */
4480 rowbytes
+= 4 - (rowbytes
% 4);
4481 pixel
= ximg
->data
+ y
* rowbytes
+ x
/ 8;
4482 /* Filter out palette info. */
4483 if (color
& 0x00ffffff)
4484 *pixel
= *pixel
| (1 << x
% 8);
4486 *pixel
= *pixel
& ~(1 << x
% 8);
4489 image_error ("XPutPixel: palette image not supported", Qnil
, Qnil
);
4492 #endif /* HAVE_NTGUI */
4494 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
4495 RGB members are set. F is the frame on which this all happens.
4496 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
4499 x_from_xcolors (struct frame
*f
, struct image
*img
, XColor
*colors
)
4502 XImagePtr oimg
= NULL
;
4506 init_color_table ();
4508 x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 0,
4511 for (y
= 0; y
< img
->height
; ++y
)
4512 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4514 unsigned long pixel
;
4515 pixel
= lookup_rgb_color (f
, p
->red
, p
->green
, p
->blue
);
4516 XPutPixel (oimg
, x
, y
, pixel
);
4520 x_clear_image_1 (f
, img
, 1, 0, 1);
4522 x_put_x_image (f
, oimg
, pixmap
, img
->width
, img
->height
);
4523 x_destroy_x_image (oimg
);
4524 img
->pixmap
= pixmap
;
4525 #ifdef COLOR_TABLE_SUPPORT
4526 img
->colors
= colors_in_color_table (&img
->ncolors
);
4527 free_color_table ();
4528 #endif /* COLOR_TABLE_SUPPORT */
4532 /* On frame F, perform edge-detection on image IMG.
4534 MATRIX is a nine-element array specifying the transformation
4535 matrix. See emboss_matrix for an example.
4537 COLOR_ADJUST is a color adjustment added to each pixel of the
4541 x_detect_edges (struct frame
*f
, struct image
*img
, int *matrix
, int color_adjust
)
4543 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4547 for (i
= sum
= 0; i
< 9; ++i
)
4548 sum
+= eabs (matrix
[i
]);
4550 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
4552 if (min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *new / img
->width
< img
->height
)
4553 memory_full (SIZE_MAX
);
4554 new = xmalloc (sizeof *new * img
->width
* img
->height
);
4556 for (y
= 0; y
< img
->height
; ++y
)
4558 p
= COLOR (new, 0, y
);
4559 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4560 p
= COLOR (new, img
->width
- 1, y
);
4561 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4564 for (x
= 1; x
< img
->width
- 1; ++x
)
4566 p
= COLOR (new, x
, 0);
4567 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4568 p
= COLOR (new, x
, img
->height
- 1);
4569 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4572 for (y
= 1; y
< img
->height
- 1; ++y
)
4574 p
= COLOR (new, 1, y
);
4576 for (x
= 1; x
< img
->width
- 1; ++x
, ++p
)
4578 int r
, g
, b
, yy
, xx
;
4581 for (yy
= y
- 1; yy
< y
+ 2; ++yy
)
4582 for (xx
= x
- 1; xx
< x
+ 2; ++xx
, ++i
)
4585 XColor
*t
= COLOR (colors
, xx
, yy
);
4586 r
+= matrix
[i
] * t
->red
;
4587 g
+= matrix
[i
] * t
->green
;
4588 b
+= matrix
[i
] * t
->blue
;
4591 r
= (r
/ sum
+ color_adjust
) & 0xffff;
4592 g
= (g
/ sum
+ color_adjust
) & 0xffff;
4593 b
= (b
/ sum
+ color_adjust
) & 0xffff;
4594 p
->red
= p
->green
= p
->blue
= COLOR_INTENSITY (r
, g
, b
);
4599 x_from_xcolors (f
, img
, new);
4605 /* Perform the pre-defined `emboss' edge-detection on image IMG
4609 x_emboss (struct frame
*f
, struct image
*img
)
4611 x_detect_edges (f
, img
, emboss_matrix
, 0xffff / 2);
4615 /* Transform image IMG which is used on frame F with a Laplace
4616 edge-detection algorithm. The result is an image that can be used
4617 to draw disabled buttons, for example. */
4620 x_laplace (struct frame
*f
, struct image
*img
)
4622 x_detect_edges (f
, img
, laplace_matrix
, 45000);
4626 /* Perform edge-detection on image IMG on frame F, with specified
4627 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
4629 MATRIX must be either
4631 - a list of at least 9 numbers in row-major form
4632 - a vector of at least 9 numbers
4634 COLOR_ADJUST nil means use a default; otherwise it must be a
4638 x_edge_detection (struct frame
*f
, struct image
*img
, Lisp_Object matrix
,
4639 Lisp_Object color_adjust
)
4647 i
< 9 && CONSP (matrix
) && NUMBERP (XCAR (matrix
));
4648 ++i
, matrix
= XCDR (matrix
))
4649 trans
[i
] = XFLOATINT (XCAR (matrix
));
4651 else if (VECTORP (matrix
) && ASIZE (matrix
) >= 9)
4653 for (i
= 0; i
< 9 && NUMBERP (AREF (matrix
, i
)); ++i
)
4654 trans
[i
] = XFLOATINT (AREF (matrix
, i
));
4657 if (NILP (color_adjust
))
4658 color_adjust
= make_number (0xffff / 2);
4660 if (i
== 9 && NUMBERP (color_adjust
))
4661 x_detect_edges (f
, img
, trans
, XFLOATINT (color_adjust
));
4665 /* Transform image IMG on frame F so that it looks disabled. */
4668 x_disable_image (struct frame
*f
, struct image
*img
)
4670 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
4672 int n_planes
= dpyinfo
->n_planes
* dpyinfo
->n_cbits
;
4674 int n_planes
= dpyinfo
->n_planes
;
4675 #endif /* HAVE_NTGUI */
4679 /* Color (or grayscale). Convert to gray, and equalize. Just
4680 drawing such images with a stipple can look very odd, so
4681 we're using this method instead. */
4682 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4684 const int h
= 15000;
4685 const int l
= 30000;
4687 for (p
= colors
, end
= colors
+ img
->width
* img
->height
;
4691 int i
= COLOR_INTENSITY (p
->red
, p
->green
, p
->blue
);
4692 int i2
= (0xffff - h
- l
) * i
/ 0xffff + l
;
4693 p
->red
= p
->green
= p
->blue
= i2
;
4696 x_from_xcolors (f
, img
, colors
);
4699 /* Draw a cross over the disabled image, if we must or if we
4701 if (n_planes
< 2 || cross_disabled_images
)
4704 #ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
4706 #define MaskForeground(f) WHITE_PIX_DEFAULT (f)
4708 Display
*dpy
= FRAME_X_DISPLAY (f
);
4709 GC gc
= XCreateGC (dpy
, img
->pixmap
, 0, NULL
);
4710 XSetForeground (dpy
, gc
, BLACK_PIX_DEFAULT (f
));
4711 XDrawLine (dpy
, img
->pixmap
, gc
, 0, 0,
4712 img
->width
- 1, img
->height
- 1);
4713 XDrawLine (dpy
, img
->pixmap
, gc
, 0, img
->height
- 1,
4719 gc
= XCreateGC (dpy
, img
->mask
, 0, NULL
);
4720 XSetForeground (dpy
, gc
, MaskForeground (f
));
4721 XDrawLine (dpy
, img
->mask
, gc
, 0, 0,
4722 img
->width
- 1, img
->height
- 1);
4723 XDrawLine (dpy
, img
->mask
, gc
, 0, img
->height
- 1,
4727 #endif /* !HAVE_NS */
4732 hdc
= get_frame_dc (f
);
4733 bmpdc
= CreateCompatibleDC (hdc
);
4734 release_frame_dc (f
, hdc
);
4736 prev
= SelectObject (bmpdc
, img
->pixmap
);
4738 SetTextColor (bmpdc
, BLACK_PIX_DEFAULT (f
));
4739 MoveToEx (bmpdc
, 0, 0, NULL
);
4740 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
4741 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
4742 LineTo (bmpdc
, img
->width
- 1, 0);
4746 SelectObject (bmpdc
, img
->mask
);
4747 SetTextColor (bmpdc
, WHITE_PIX_DEFAULT (f
));
4748 MoveToEx (bmpdc
, 0, 0, NULL
);
4749 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
4750 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
4751 LineTo (bmpdc
, img
->width
- 1, 0);
4753 SelectObject (bmpdc
, prev
);
4755 #endif /* HAVE_NTGUI */
4760 /* Build a mask for image IMG which is used on frame F. FILE is the
4761 name of an image file, for error messages. HOW determines how to
4762 determine the background color of IMG. If it is a list '(R G B)',
4763 with R, G, and B being integers >= 0, take that as the color of the
4764 background. Otherwise, determine the background color of IMG
4768 x_build_heuristic_mask (struct frame
*f
, struct image
*img
, Lisp_Object how
)
4770 XImagePtr_or_DC ximg
;
4778 #endif /* HAVE_NTGUI */
4780 bool rc
, use_img_background
;
4781 unsigned long bg
= 0;
4785 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
4786 img
->mask
= NO_PIXMAP
;
4787 img
->background_transparent_valid
= 0;
4792 /* Create an image and pixmap serving as mask. */
4793 rc
= x_create_x_image_and_pixmap (f
, img
->width
, img
->height
, 1,
4794 &mask_img
, &img
->mask
);
4797 #endif /* !HAVE_NS */
4799 /* Get the X image of IMG->pixmap. */
4800 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
, 0, 0,
4801 img
->width
, img
->height
,
4804 /* Create the bit array serving as mask. */
4805 row_width
= (img
->width
+ 7) / 8;
4806 mask_img
= xzalloc (row_width
* img
->height
);
4808 /* Create a memory device context for IMG->pixmap. */
4809 frame_dc
= get_frame_dc (f
);
4810 ximg
= CreateCompatibleDC (frame_dc
);
4811 release_frame_dc (f
, frame_dc
);
4812 prev
= SelectObject (ximg
, img
->pixmap
);
4813 #endif /* HAVE_NTGUI */
4815 /* Determine the background color of ximg. If HOW is `(R G B)'
4816 take that as color. Otherwise, use the image's background color. */
4817 use_img_background
= 1;
4823 for (i
= 0; i
< 3 && CONSP (how
) && NATNUMP (XCAR (how
)); ++i
)
4825 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
4829 if (i
== 3 && NILP (how
))
4831 char color_name
[30];
4832 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
4835 0x00ffffff & /* Filter out palette info. */
4836 #endif /* HAVE_NTGUI */
4837 x_alloc_image_color (f
, img
, build_string (color_name
), 0));
4838 use_img_background
= 0;
4842 if (use_img_background
)
4843 bg
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
4845 /* Set all bits in mask_img to 1 whose color in ximg is different
4846 from the background color bg. */
4848 for (y
= 0; y
< img
->height
; ++y
)
4849 for (x
= 0; x
< img
->width
; ++x
)
4851 XPutPixel (mask_img
, x
, y
, (XGetPixel (ximg
, x
, y
) != bg
4852 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
));
4854 if (XGetPixel (ximg
, x
, y
) == bg
)
4855 ns_set_alpha (ximg
, x
, y
, 0);
4856 #endif /* HAVE_NS */
4858 /* Fill in the background_transparent field while we have the mask handy. */
4859 image_background_transparent (img
, f
, mask_img
);
4861 /* Put mask_img into img->mask. */
4862 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
4863 x_destroy_x_image (mask_img
);
4864 #endif /* !HAVE_NS */
4866 for (y
= 0; y
< img
->height
; ++y
)
4867 for (x
= 0; x
< img
->width
; ++x
)
4869 COLORREF p
= GetPixel (ximg
, x
, y
);
4871 mask_img
[y
* row_width
+ x
/ 8] |= 1 << (x
% 8);
4874 /* Create the mask image. */
4875 img
->mask
= w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
,
4877 /* Fill in the background_transparent field while we have the mask handy. */
4878 SelectObject (ximg
, img
->mask
);
4879 image_background_transparent (img
, f
, ximg
);
4881 /* Was: x_destroy_x_image ((XImagePtr )mask_img); which seems bogus ++kfs */
4883 #endif /* HAVE_NTGUI */
4885 Destroy_Image (ximg
, prev
);
4889 /***********************************************************************
4890 PBM (mono, gray, color)
4891 ***********************************************************************/
4893 static bool pbm_image_p (Lisp_Object object
);
4894 static bool pbm_load (struct frame
*f
, struct image
*img
);
4896 /* The symbol `pbm' identifying images of this type. */
4898 static Lisp_Object Qpbm
;
4900 /* Indices of image specification fields in gs_format, below. */
4902 enum pbm_keyword_index
4918 /* Vector of image_keyword structures describing the format
4919 of valid user-defined image specifications. */
4921 static const struct image_keyword pbm_format
[PBM_LAST
] =
4923 {":type", IMAGE_SYMBOL_VALUE
, 1},
4924 {":file", IMAGE_STRING_VALUE
, 0},
4925 {":data", IMAGE_STRING_VALUE
, 0},
4926 {":ascent", IMAGE_ASCENT_VALUE
, 0},
4927 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
4928 {":relief", IMAGE_INTEGER_VALUE
, 0},
4929 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4930 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4931 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
4932 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
4933 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
4936 /* Structure describing the image type `pbm'. */
4938 static struct image_type pbm_type
=
4949 /* Return true if OBJECT is a valid PBM image specification. */
4952 pbm_image_p (Lisp_Object object
)
4954 struct image_keyword fmt
[PBM_LAST
];
4956 memcpy (fmt
, pbm_format
, sizeof fmt
);
4958 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
))
4961 /* Must specify either :data or :file. */
4962 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
4966 /* Scan a decimal number from *S and return it. Advance *S while
4967 reading the number. END is the end of the string. Value is -1 at
4971 pbm_scan_number (unsigned char **s
, unsigned char *end
)
4973 int c
= 0, val
= -1;
4977 /* Skip white-space. */
4978 while (*s
< end
&& (c
= *(*s
)++, c_isspace (c
)))
4983 /* Skip comment to end of line. */
4984 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
4987 else if (c_isdigit (c
))
4989 /* Read decimal number. */
4991 while (*s
< end
&& (c
= *(*s
)++, c_isdigit (c
)))
4992 val
= 10 * val
+ c
- '0';
5003 /* Load PBM image IMG for use on frame F. */
5006 pbm_load (struct frame
*f
, struct image
*img
)
5010 int width
, height
, max_color_idx
= 0;
5012 Lisp_Object file
, specified_file
;
5013 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
5014 unsigned char *contents
= NULL
;
5015 unsigned char *end
, *p
;
5018 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5020 if (STRINGP (specified_file
))
5022 file
= x_find_image_file (specified_file
);
5023 if (!STRINGP (file
))
5025 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5029 contents
= slurp_file (SSDATA (file
), &size
);
5030 if (contents
== NULL
)
5032 image_error ("Error reading `%s'", file
, Qnil
);
5037 end
= contents
+ size
;
5042 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5043 if (!STRINGP (data
))
5045 image_error ("Invalid image data `%s'", data
, Qnil
);
5049 end
= p
+ SBYTES (data
);
5052 /* Check magic number. */
5053 if (end
- p
< 2 || *p
++ != 'P')
5055 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5064 raw_p
= 0, type
= PBM_MONO
;
5068 raw_p
= 0, type
= PBM_GRAY
;
5072 raw_p
= 0, type
= PBM_COLOR
;
5076 raw_p
= 1, type
= PBM_MONO
;
5080 raw_p
= 1, type
= PBM_GRAY
;
5084 raw_p
= 1, type
= PBM_COLOR
;
5088 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5092 /* Read width, height, maximum color-component. Characters
5093 starting with `#' up to the end of a line are ignored. */
5094 width
= pbm_scan_number (&p
, end
);
5095 height
= pbm_scan_number (&p
, end
);
5097 if (type
!= PBM_MONO
)
5099 max_color_idx
= pbm_scan_number (&p
, end
);
5100 if (max_color_idx
> 65535 || max_color_idx
< 0)
5102 image_error ("Unsupported maximum PBM color value", Qnil
, Qnil
);
5107 if (!check_image_size (f
, width
, height
))
5109 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
5113 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
5114 &ximg
, &img
->pixmap
))
5117 /* Initialize the color hash table. */
5118 init_color_table ();
5120 if (type
== PBM_MONO
)
5123 struct image_keyword fmt
[PBM_LAST
];
5124 unsigned long fg
= FRAME_FOREGROUND_PIXEL (f
);
5125 unsigned long bg
= FRAME_BACKGROUND_PIXEL (f
);
5127 /* Parse the image specification. */
5128 memcpy (fmt
, pbm_format
, sizeof fmt
);
5129 parse_image_spec (img
->spec
, fmt
, PBM_LAST
, Qpbm
);
5131 /* Get foreground and background colors, maybe allocate colors. */
5132 if (fmt
[PBM_FOREGROUND
].count
5133 && STRINGP (fmt
[PBM_FOREGROUND
].value
))
5134 fg
= x_alloc_image_color (f
, img
, fmt
[PBM_FOREGROUND
].value
, fg
);
5135 if (fmt
[PBM_BACKGROUND
].count
5136 && STRINGP (fmt
[PBM_BACKGROUND
].value
))
5138 bg
= x_alloc_image_color (f
, img
, fmt
[PBM_BACKGROUND
].value
, bg
);
5139 img
->background
= bg
;
5140 img
->background_valid
= 1;
5143 for (y
= 0; y
< height
; ++y
)
5144 for (x
= 0; x
< width
; ++x
)
5152 x_destroy_x_image (ximg
);
5153 x_clear_image (f
, img
);
5154 image_error ("Invalid image size in image `%s'",
5164 g
= pbm_scan_number (&p
, end
);
5166 XPutPixel (ximg
, x
, y
, g
? fg
: bg
);
5171 int expected_size
= height
* width
;
5172 if (max_color_idx
> 255)
5174 if (type
== PBM_COLOR
)
5177 if (raw_p
&& p
+ expected_size
> end
)
5179 x_destroy_x_image (ximg
);
5180 x_clear_image (f
, img
);
5181 image_error ("Invalid image size in image `%s'",
5186 for (y
= 0; y
< height
; ++y
)
5187 for (x
= 0; x
< width
; ++x
)
5191 if (type
== PBM_GRAY
&& raw_p
)
5194 if (max_color_idx
> 255)
5195 r
= g
= b
= r
* 256 + *p
++;
5197 else if (type
== PBM_GRAY
)
5198 r
= g
= b
= pbm_scan_number (&p
, end
);
5202 if (max_color_idx
> 255)
5205 if (max_color_idx
> 255)
5208 if (max_color_idx
> 255)
5213 r
= pbm_scan_number (&p
, end
);
5214 g
= pbm_scan_number (&p
, end
);
5215 b
= pbm_scan_number (&p
, end
);
5218 if (r
< 0 || g
< 0 || b
< 0)
5220 x_destroy_x_image (ximg
);
5221 image_error ("Invalid pixel value in image `%s'",
5226 /* RGB values are now in the range 0..max_color_idx.
5227 Scale this to the range 0..0xffff supported by X. */
5228 r
= (double) r
* 65535 / max_color_idx
;
5229 g
= (double) g
* 65535 / max_color_idx
;
5230 b
= (double) b
* 65535 / max_color_idx
;
5231 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
5235 #ifdef COLOR_TABLE_SUPPORT
5236 /* Store in IMG->colors the colors allocated for the image, and
5237 free the color table. */
5238 img
->colors
= colors_in_color_table (&img
->ncolors
);
5239 free_color_table ();
5240 #endif /* COLOR_TABLE_SUPPORT */
5243 img
->height
= height
;
5245 /* Maybe fill in the background field while we have ximg handy. */
5247 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
5248 /* Casting avoids a GCC warning. */
5249 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
5251 /* Put the image into a pixmap. */
5252 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
5253 x_destroy_x_image (ximg
);
5255 /* X and W32 versions did it here, MAC version above. ++kfs
5257 img->height = height; */
5264 /***********************************************************************
5266 ***********************************************************************/
5268 #if defined (HAVE_PNG) || defined (HAVE_NS)
5270 /* Function prototypes. */
5272 static bool png_image_p (Lisp_Object object
);
5273 static bool png_load (struct frame
*f
, struct image
*img
);
5275 /* The symbol `png' identifying images of this type. */
5277 static Lisp_Object Qpng
;
5279 /* Indices of image specification fields in png_format, below. */
5281 enum png_keyword_index
5296 /* Vector of image_keyword structures describing the format
5297 of valid user-defined image specifications. */
5299 static const struct image_keyword png_format
[PNG_LAST
] =
5301 {":type", IMAGE_SYMBOL_VALUE
, 1},
5302 {":data", IMAGE_STRING_VALUE
, 0},
5303 {":file", IMAGE_STRING_VALUE
, 0},
5304 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5305 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
5306 {":relief", IMAGE_INTEGER_VALUE
, 0},
5307 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5308 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5309 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5310 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
5313 #if defined HAVE_NTGUI && defined WINDOWSNT
5314 static bool init_png_functions (void);
5316 #define init_png_functions NULL
5319 /* Structure describing the image type `png'. */
5321 static struct image_type png_type
=
5331 /* Return true if OBJECT is a valid PNG image specification. */
5334 png_image_p (Lisp_Object object
)
5336 struct image_keyword fmt
[PNG_LAST
];
5337 memcpy (fmt
, png_format
, sizeof fmt
);
5339 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
5342 /* Must specify either the :data or :file keyword. */
5343 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
5346 #endif /* HAVE_PNG || HAVE_NS */
5352 /* PNG library details. */
5354 DEF_IMGLIB_FN (png_voidp
, png_get_io_ptr
, (png_structp
));
5355 DEF_IMGLIB_FN (int, png_sig_cmp
, (png_bytep
, png_size_t
, png_size_t
));
5356 DEF_IMGLIB_FN (png_structp
, png_create_read_struct
, (png_const_charp
, png_voidp
,
5357 png_error_ptr
, png_error_ptr
));
5358 DEF_IMGLIB_FN (png_infop
, png_create_info_struct
, (png_structp
));
5359 DEF_IMGLIB_FN (void, png_destroy_read_struct
, (png_structpp
, png_infopp
, png_infopp
));
5360 DEF_IMGLIB_FN (void, png_set_read_fn
, (png_structp
, png_voidp
, png_rw_ptr
));
5361 DEF_IMGLIB_FN (void, png_set_sig_bytes
, (png_structp
, int));
5362 DEF_IMGLIB_FN (void, png_read_info
, (png_structp
, png_infop
));
5363 DEF_IMGLIB_FN (png_uint_32
, png_get_IHDR
, (png_structp
, png_infop
,
5364 png_uint_32
*, png_uint_32
*,
5365 int *, int *, int *, int *, int *));
5366 DEF_IMGLIB_FN (png_uint_32
, png_get_valid
, (png_structp
, png_infop
, png_uint_32
));
5367 DEF_IMGLIB_FN (void, png_set_strip_16
, (png_structp
));
5368 DEF_IMGLIB_FN (void, png_set_expand
, (png_structp
));
5369 DEF_IMGLIB_FN (void, png_set_gray_to_rgb
, (png_structp
));
5370 DEF_IMGLIB_FN (void, png_set_background
, (png_structp
, png_color_16p
,
5372 DEF_IMGLIB_FN (png_uint_32
, png_get_bKGD
, (png_structp
, png_infop
, png_color_16p
*));
5373 DEF_IMGLIB_FN (void, png_read_update_info
, (png_structp
, png_infop
));
5374 DEF_IMGLIB_FN (png_byte
, png_get_channels
, (png_structp
, png_infop
));
5375 DEF_IMGLIB_FN (png_size_t
, png_get_rowbytes
, (png_structp
, png_infop
));
5376 DEF_IMGLIB_FN (void, png_read_image
, (png_structp
, png_bytepp
));
5377 DEF_IMGLIB_FN (void, png_read_end
, (png_structp
, png_infop
));
5378 DEF_IMGLIB_FN (void, png_error
, (png_structp
, png_const_charp
));
5380 #if (PNG_LIBPNG_VER >= 10500)
5381 DEF_IMGLIB_FN (void, png_longjmp
, (png_structp
, int));
5382 DEF_IMGLIB_FN (jmp_buf *, png_set_longjmp_fn
, (png_structp
, png_longjmp_ptr
, size_t));
5383 #endif /* libpng version >= 1.5 */
5386 init_png_functions (void)
5390 if (!(library
= w32_delayed_load (Qpng
)))
5393 LOAD_IMGLIB_FN (library
, png_get_io_ptr
);
5394 LOAD_IMGLIB_FN (library
, png_sig_cmp
);
5395 LOAD_IMGLIB_FN (library
, png_create_read_struct
);
5396 LOAD_IMGLIB_FN (library
, png_create_info_struct
);
5397 LOAD_IMGLIB_FN (library
, png_destroy_read_struct
);
5398 LOAD_IMGLIB_FN (library
, png_set_read_fn
);
5399 LOAD_IMGLIB_FN (library
, png_set_sig_bytes
);
5400 LOAD_IMGLIB_FN (library
, png_read_info
);
5401 LOAD_IMGLIB_FN (library
, png_get_IHDR
);
5402 LOAD_IMGLIB_FN (library
, png_get_valid
);
5403 LOAD_IMGLIB_FN (library
, png_set_strip_16
);
5404 LOAD_IMGLIB_FN (library
, png_set_expand
);
5405 LOAD_IMGLIB_FN (library
, png_set_gray_to_rgb
);
5406 LOAD_IMGLIB_FN (library
, png_set_background
);
5407 LOAD_IMGLIB_FN (library
, png_get_bKGD
);
5408 LOAD_IMGLIB_FN (library
, png_read_update_info
);
5409 LOAD_IMGLIB_FN (library
, png_get_channels
);
5410 LOAD_IMGLIB_FN (library
, png_get_rowbytes
);
5411 LOAD_IMGLIB_FN (library
, png_read_image
);
5412 LOAD_IMGLIB_FN (library
, png_read_end
);
5413 LOAD_IMGLIB_FN (library
, png_error
);
5415 #if (PNG_LIBPNG_VER >= 10500)
5416 LOAD_IMGLIB_FN (library
, png_longjmp
);
5417 LOAD_IMGLIB_FN (library
, png_set_longjmp_fn
);
5418 #endif /* libpng version >= 1.5 */
5424 #define fn_png_get_io_ptr png_get_io_ptr
5425 #define fn_png_sig_cmp png_sig_cmp
5426 #define fn_png_create_read_struct png_create_read_struct
5427 #define fn_png_create_info_struct png_create_info_struct
5428 #define fn_png_destroy_read_struct png_destroy_read_struct
5429 #define fn_png_set_read_fn png_set_read_fn
5430 #define fn_png_set_sig_bytes png_set_sig_bytes
5431 #define fn_png_read_info png_read_info
5432 #define fn_png_get_IHDR png_get_IHDR
5433 #define fn_png_get_valid png_get_valid
5434 #define fn_png_set_strip_16 png_set_strip_16
5435 #define fn_png_set_expand png_set_expand
5436 #define fn_png_set_gray_to_rgb png_set_gray_to_rgb
5437 #define fn_png_set_background png_set_background
5438 #define fn_png_get_bKGD png_get_bKGD
5439 #define fn_png_read_update_info png_read_update_info
5440 #define fn_png_get_channels png_get_channels
5441 #define fn_png_get_rowbytes png_get_rowbytes
5442 #define fn_png_read_image png_read_image
5443 #define fn_png_read_end png_read_end
5444 #define fn_png_error png_error
5446 #if (PNG_LIBPNG_VER >= 10500)
5447 #define fn_png_longjmp png_longjmp
5448 #define fn_png_set_longjmp_fn png_set_longjmp_fn
5449 #endif /* libpng version >= 1.5 */
5451 #endif /* WINDOWSNT */
5453 /* Possibly inefficient/inexact substitutes for _setjmp and _longjmp.
5454 Do not use sys_setjmp, as PNG supports only jmp_buf. The _longjmp
5455 substitute may munge the signal mask, but that should be OK here.
5456 MinGW (MS-Windows) uses _setjmp and defines setjmp to _setjmp in
5457 the system header setjmp.h; don't mess up that. */
5458 #ifndef HAVE__SETJMP
5459 # define _setjmp(j) setjmp (j)
5460 # define _longjmp longjmp
5463 #if (PNG_LIBPNG_VER < 10500)
5464 #define PNG_LONGJMP(ptr) (_longjmp ((ptr)->jmpbuf, 1))
5465 #define PNG_JMPBUF(ptr) ((ptr)->jmpbuf)
5467 /* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908) */
5468 #define PNG_LONGJMP(ptr) (fn_png_longjmp ((ptr), 1))
5469 #define PNG_JMPBUF(ptr) \
5470 (*fn_png_set_longjmp_fn ((ptr), _longjmp, sizeof (jmp_buf)))
5473 /* Error and warning handlers installed when the PNG library
5476 static _Noreturn
void
5477 my_png_error (png_struct
*png_ptr
, const char *msg
)
5479 eassert (png_ptr
!= NULL
);
5480 /* Avoid compiler warning about deprecated direct access to
5481 png_ptr's fields in libpng versions 1.4.x. */
5482 image_error ("PNG error: %s", build_string (msg
), Qnil
);
5483 PNG_LONGJMP (png_ptr
);
5488 my_png_warning (png_struct
*png_ptr
, const char *msg
)
5490 eassert (png_ptr
!= NULL
);
5491 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
5494 /* Memory source for PNG decoding. */
5496 struct png_memory_storage
5498 unsigned char *bytes
; /* The data */
5499 ptrdiff_t len
; /* How big is it? */
5500 ptrdiff_t index
; /* Where are we? */
5504 /* Function set as reader function when reading PNG image from memory.
5505 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5506 bytes from the input to DATA. */
5509 png_read_from_memory (png_structp png_ptr
, png_bytep data
, png_size_t length
)
5511 struct png_memory_storage
*tbr
5512 = (struct png_memory_storage
*) fn_png_get_io_ptr (png_ptr
);
5514 if (length
> tbr
->len
- tbr
->index
)
5515 fn_png_error (png_ptr
, "Read error");
5517 memcpy (data
, tbr
->bytes
+ tbr
->index
, length
);
5518 tbr
->index
= tbr
->index
+ length
;
5522 /* Function set as reader function when reading PNG image from a file.
5523 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5524 bytes from the input to DATA. */
5527 png_read_from_file (png_structp png_ptr
, png_bytep data
, png_size_t length
)
5529 FILE *fp
= (FILE *) fn_png_get_io_ptr (png_ptr
);
5531 if (fread (data
, 1, length
, fp
) < length
)
5532 fn_png_error (png_ptr
, "Read error");
5536 /* Load PNG image IMG for use on frame F. Value is true if
5539 struct png_load_context
5541 /* These are members so that longjmp doesn't munge local variables. */
5542 png_struct
*png_ptr
;
5551 png_load_body (struct frame
*f
, struct image
*img
, struct png_load_context
*c
)
5553 Lisp_Object file
, specified_file
;
5554 Lisp_Object specified_data
;
5557 XImagePtr ximg
, mask_img
= NULL
;
5558 png_struct
*png_ptr
;
5559 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
5562 png_byte
*pixels
= NULL
;
5563 png_byte
**rows
= NULL
;
5564 png_uint_32 width
, height
;
5565 int bit_depth
, color_type
, interlace_type
;
5567 png_uint_32 row_bytes
;
5569 struct png_memory_storage tbr
; /* Data to be read */
5571 /* Find out what file to load. */
5572 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5573 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5575 if (NILP (specified_data
))
5577 file
= x_find_image_file (specified_file
);
5578 if (!STRINGP (file
))
5580 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5584 /* Open the image file. */
5585 fp
= fopen (SSDATA (file
), "rb");
5588 image_error ("Cannot open image file `%s'", file
, Qnil
);
5592 /* Check PNG signature. */
5593 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
5594 || fn_png_sig_cmp (sig
, 0, sizeof sig
))
5596 image_error ("Not a PNG file: `%s'", file
, Qnil
);
5603 if (!STRINGP (specified_data
))
5605 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
5609 /* Read from memory. */
5610 tbr
.bytes
= SDATA (specified_data
);
5611 tbr
.len
= SBYTES (specified_data
);
5614 /* Check PNG signature. */
5615 if (tbr
.len
< sizeof sig
5616 || fn_png_sig_cmp (tbr
.bytes
, 0, sizeof sig
))
5618 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
5622 /* Need to skip past the signature. */
5623 tbr
.bytes
+= sizeof (sig
);
5626 /* Initialize read and info structs for PNG lib. */
5627 png_ptr
= fn_png_create_read_struct (PNG_LIBPNG_VER_STRING
,
5632 info_ptr
= fn_png_create_info_struct (png_ptr
);
5633 end_info
= fn_png_create_info_struct (png_ptr
);
5636 c
->png_ptr
= png_ptr
;
5637 c
->info_ptr
= info_ptr
;
5638 c
->end_info
= end_info
;
5643 if (! (info_ptr
&& end_info
))
5645 fn_png_destroy_read_struct (&c
->png_ptr
, &c
->info_ptr
, &c
->end_info
);
5650 if (fp
) fclose (fp
);
5654 /* Set error jump-back. We come back here when the PNG library
5655 detects an error. */
5656 if (_setjmp (PNG_JMPBUF (png_ptr
)))
5660 fn_png_destroy_read_struct (&c
->png_ptr
, &c
->info_ptr
, &c
->end_info
);
5668 /* Silence a bogus diagnostic; see GCC bug 54561. */
5669 IF_LINT (fp
= c
->fp
);
5671 /* Read image info. */
5672 if (!NILP (specified_data
))
5673 fn_png_set_read_fn (png_ptr
, (void *) &tbr
, png_read_from_memory
);
5675 fn_png_set_read_fn (png_ptr
, (void *) fp
, png_read_from_file
);
5677 fn_png_set_sig_bytes (png_ptr
, sizeof sig
);
5678 fn_png_read_info (png_ptr
, info_ptr
);
5679 fn_png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
5680 &interlace_type
, NULL
, NULL
);
5682 if (! (width
<= INT_MAX
&& height
<= INT_MAX
5683 && check_image_size (f
, width
, height
)))
5685 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
5689 /* Create the X image and pixmap now, so that the work below can be
5690 omitted if the image is too large for X. */
5691 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
,
5695 /* If image contains simply transparency data, we prefer to
5696 construct a clipping mask. */
5697 if (fn_png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
5702 /* This function is easier to write if we only have to handle
5703 one data format: RGB or RGBA with 8 bits per channel. Let's
5704 transform other formats into that format. */
5706 /* Strip more than 8 bits per channel. */
5707 if (bit_depth
== 16)
5708 fn_png_set_strip_16 (png_ptr
);
5710 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
5712 fn_png_set_expand (png_ptr
);
5714 /* Convert grayscale images to RGB. */
5715 if (color_type
== PNG_COLOR_TYPE_GRAY
5716 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
5717 fn_png_set_gray_to_rgb (png_ptr
);
5719 /* Handle alpha channel by combining the image with a background
5720 color. Do this only if a real alpha channel is supplied. For
5721 simple transparency, we prefer a clipping mask. */
5724 /* png_color_16 *image_bg; */
5725 Lisp_Object specified_bg
5726 = image_spec_value (img
->spec
, QCbackground
, NULL
);
5727 int shift
= (bit_depth
== 16) ? 0 : 8;
5729 if (STRINGP (specified_bg
))
5730 /* The user specified `:background', use that. */
5733 if (x_defined_color (f
, SSDATA (specified_bg
), &color
, 0))
5735 png_color_16 user_bg
;
5737 memset (&user_bg
, 0, sizeof user_bg
);
5738 user_bg
.red
= color
.red
>> shift
;
5739 user_bg
.green
= color
.green
>> shift
;
5740 user_bg
.blue
= color
.blue
>> shift
;
5742 fn_png_set_background (png_ptr
, &user_bg
,
5743 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
5748 /* We use the current frame background, ignoring any default
5749 background color set by the image. */
5750 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
5752 png_color_16 frame_background
;
5754 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
5755 x_query_color (f
, &color
);
5757 memset (&frame_background
, 0, sizeof frame_background
);
5758 frame_background
.red
= color
.red
>> shift
;
5759 frame_background
.green
= color
.green
>> shift
;
5760 frame_background
.blue
= color
.blue
>> shift
;
5761 #endif /* HAVE_X_WINDOWS */
5763 fn_png_set_background (png_ptr
, &frame_background
,
5764 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
5768 /* Update info structure. */
5769 fn_png_read_update_info (png_ptr
, info_ptr
);
5771 /* Get number of channels. Valid values are 1 for grayscale images
5772 and images with a palette, 2 for grayscale images with transparency
5773 information (alpha channel), 3 for RGB images, and 4 for RGB
5774 images with alpha channel, i.e. RGBA. If conversions above were
5775 sufficient we should only have 3 or 4 channels here. */
5776 channels
= fn_png_get_channels (png_ptr
, info_ptr
);
5777 eassert (channels
== 3 || channels
== 4);
5779 /* Number of bytes needed for one row of the image. */
5780 row_bytes
= fn_png_get_rowbytes (png_ptr
, info_ptr
);
5782 /* Allocate memory for the image. */
5783 if (min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *rows
< height
5784 || min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *pixels
/ height
< row_bytes
)
5785 memory_full (SIZE_MAX
);
5786 c
->pixels
= pixels
= xmalloc (sizeof *pixels
* row_bytes
* height
);
5787 c
->rows
= rows
= xmalloc (height
* sizeof *rows
);
5788 for (i
= 0; i
< height
; ++i
)
5789 rows
[i
] = pixels
+ i
* row_bytes
;
5791 /* Read the entire image. */
5792 fn_png_read_image (png_ptr
, rows
);
5793 fn_png_read_end (png_ptr
, info_ptr
);
5800 /* Create an image and pixmap serving as mask if the PNG image
5801 contains an alpha channel. */
5804 && !x_create_x_image_and_pixmap (f
, width
, height
, 1,
5805 &mask_img
, &img
->mask
))
5807 x_destroy_x_image (ximg
);
5808 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
5809 img
->pixmap
= NO_PIXMAP
;
5813 /* Fill the X image and mask from PNG data. */
5814 init_color_table ();
5816 for (y
= 0; y
< height
; ++y
)
5818 png_byte
*p
= rows
[y
];
5820 for (x
= 0; x
< width
; ++x
)
5827 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
5828 /* An alpha channel, aka mask channel, associates variable
5829 transparency with an image. Where other image formats
5830 support binary transparency---fully transparent or fully
5831 opaque---PNG allows up to 254 levels of partial transparency.
5832 The PNG library implements partial transparency by combining
5833 the image with a specified background color.
5835 I'm not sure how to handle this here nicely: because the
5836 background on which the image is displayed may change, for
5837 real alpha channel support, it would be necessary to create
5838 a new image for each possible background.
5840 What I'm doing now is that a mask is created if we have
5841 boolean transparency information. Otherwise I'm using
5842 the frame's background color to combine the image with. */
5847 XPutPixel (mask_img
, x
, y
, *p
> 0 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
);
5853 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
5854 /* Set IMG's background color from the PNG image, unless the user
5858 if (fn_png_get_bKGD (png_ptr
, info_ptr
, &bg
))
5860 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
5861 img
->background_valid
= 1;
5865 #ifdef COLOR_TABLE_SUPPORT
5866 /* Remember colors allocated for this image. */
5867 img
->colors
= colors_in_color_table (&img
->ncolors
);
5868 free_color_table ();
5869 #endif /* COLOR_TABLE_SUPPORT */
5872 fn_png_destroy_read_struct (&c
->png_ptr
, &c
->info_ptr
, &c
->end_info
);
5877 img
->height
= height
;
5879 /* Maybe fill in the background field while we have ximg handy.
5880 Casting avoids a GCC warning. */
5881 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
5883 /* Put the image into the pixmap, then free the X image and its buffer. */
5884 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
5885 x_destroy_x_image (ximg
);
5887 /* Same for the mask. */
5890 /* Fill in the background_transparent field while we have the
5891 mask handy. Casting avoids a GCC warning. */
5892 image_background_transparent (img
, f
, (XImagePtr_or_DC
)mask_img
);
5894 x_put_x_image (f
, mask_img
, img
->mask
, img
->width
, img
->height
);
5895 x_destroy_x_image (mask_img
);
5902 png_load (struct frame
*f
, struct image
*img
)
5904 struct png_load_context c
;
5905 return png_load_body (f
, img
, &c
);
5908 #else /* HAVE_PNG */
5912 png_load (struct frame
*f
, struct image
*img
)
5914 return ns_load_image (f
, img
,
5915 image_spec_value (img
->spec
, QCfile
, NULL
),
5916 image_spec_value (img
->spec
, QCdata
, NULL
));
5918 #endif /* HAVE_NS */
5921 #endif /* !HAVE_PNG */
5925 /***********************************************************************
5927 ***********************************************************************/
5929 #if defined (HAVE_JPEG) || defined (HAVE_NS)
5931 static bool jpeg_image_p (Lisp_Object object
);
5932 static bool jpeg_load (struct frame
*f
, struct image
*img
);
5934 /* The symbol `jpeg' identifying images of this type. */
5936 static Lisp_Object Qjpeg
;
5938 /* Indices of image specification fields in gs_format, below. */
5940 enum jpeg_keyword_index
5949 JPEG_HEURISTIC_MASK
,
5955 /* Vector of image_keyword structures describing the format
5956 of valid user-defined image specifications. */
5958 static const struct image_keyword jpeg_format
[JPEG_LAST
] =
5960 {":type", IMAGE_SYMBOL_VALUE
, 1},
5961 {":data", IMAGE_STRING_VALUE
, 0},
5962 {":file", IMAGE_STRING_VALUE
, 0},
5963 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5964 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
5965 {":relief", IMAGE_INTEGER_VALUE
, 0},
5966 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5967 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5968 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5969 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
5972 #if defined HAVE_NTGUI && defined WINDOWSNT
5973 static bool init_jpeg_functions (void);
5975 #define init_jpeg_functions NULL
5978 /* Structure describing the image type `jpeg'. */
5980 static struct image_type jpeg_type
=
5986 init_jpeg_functions
,
5990 /* Return true if OBJECT is a valid JPEG image specification. */
5993 jpeg_image_p (Lisp_Object object
)
5995 struct image_keyword fmt
[JPEG_LAST
];
5997 memcpy (fmt
, jpeg_format
, sizeof fmt
);
5999 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
6002 /* Must specify either the :data or :file keyword. */
6003 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
6006 #endif /* HAVE_JPEG || HAVE_NS */
6010 /* Work around a warning about HAVE_STDLIB_H being redefined in
6012 #ifdef HAVE_STDLIB_H
6013 #undef HAVE_STDLIB_H
6014 #endif /* HAVE_STLIB_H */
6016 #if defined (HAVE_NTGUI) && !defined (__WIN32__)
6017 /* In older releases of the jpeg library, jpeglib.h will define boolean
6018 differently depending on __WIN32__, so make sure it is defined. */
6022 /* rpcndr.h (via windows.h) and jpeglib.h both define boolean types.
6023 Some versions of jpeglib try to detect whether rpcndr.h is loaded,
6024 using the Windows boolean type instead of the jpeglib boolean type
6025 if so. Cygwin jpeglib, however, doesn't try to detect whether its
6026 headers are included along with windows.h, so under Cygwin, jpeglib
6027 attempts to define a conflicting boolean type. Worse, forcing
6028 Cygwin jpeglib headers to use the Windows boolean type doesn't work
6029 because it created an ABI incompatibility between the
6030 already-compiled jpeg library and the header interface definition.
6032 The best we can do is to define jpeglib's boolean type to a
6033 different name. This name, jpeg_boolean, remains in effect through
6034 the rest of image.c.
6036 #if defined CYGWIN && defined HAVE_NTGUI
6037 #define boolean jpeg_boolean
6039 #include <jpeglib.h>
6044 /* JPEG library details. */
6045 DEF_IMGLIB_FN (void, jpeg_CreateDecompress
, (j_decompress_ptr
, int, size_t));
6046 DEF_IMGLIB_FN (boolean
, jpeg_start_decompress
, (j_decompress_ptr
));
6047 DEF_IMGLIB_FN (boolean
, jpeg_finish_decompress
, (j_decompress_ptr
));
6048 DEF_IMGLIB_FN (void, jpeg_destroy_decompress
, (j_decompress_ptr
));
6049 DEF_IMGLIB_FN (int, jpeg_read_header
, (j_decompress_ptr
, boolean
));
6050 DEF_IMGLIB_FN (JDIMENSION
, jpeg_read_scanlines
, (j_decompress_ptr
, JSAMPARRAY
, JDIMENSION
));
6051 DEF_IMGLIB_FN (struct jpeg_error_mgr
*, jpeg_std_error
, (struct jpeg_error_mgr
*));
6052 DEF_IMGLIB_FN (boolean
, jpeg_resync_to_restart
, (j_decompress_ptr
, int));
6055 init_jpeg_functions (void)
6059 if (!(library
= w32_delayed_load (Qjpeg
)))
6062 LOAD_IMGLIB_FN (library
, jpeg_finish_decompress
);
6063 LOAD_IMGLIB_FN (library
, jpeg_read_scanlines
);
6064 LOAD_IMGLIB_FN (library
, jpeg_start_decompress
);
6065 LOAD_IMGLIB_FN (library
, jpeg_read_header
);
6066 LOAD_IMGLIB_FN (library
, jpeg_CreateDecompress
);
6067 LOAD_IMGLIB_FN (library
, jpeg_destroy_decompress
);
6068 LOAD_IMGLIB_FN (library
, jpeg_std_error
);
6069 LOAD_IMGLIB_FN (library
, jpeg_resync_to_restart
);
6073 /* Wrapper since we can't directly assign the function pointer
6074 to another function pointer that was declared more completely easily. */
6076 jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo
, int desired
)
6078 return fn_jpeg_resync_to_restart (cinfo
, desired
);
6083 #define fn_jpeg_CreateDecompress(a,b,c) jpeg_create_decompress (a)
6084 #define fn_jpeg_start_decompress jpeg_start_decompress
6085 #define fn_jpeg_finish_decompress jpeg_finish_decompress
6086 #define fn_jpeg_destroy_decompress jpeg_destroy_decompress
6087 #define fn_jpeg_read_header jpeg_read_header
6088 #define fn_jpeg_read_scanlines jpeg_read_scanlines
6089 #define fn_jpeg_std_error jpeg_std_error
6090 #define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart
6092 #endif /* WINDOWSNT */
6094 struct my_jpeg_error_mgr
6096 struct jpeg_error_mgr pub
;
6097 sys_jmp_buf setjmp_buffer
;
6099 /* The remaining members are so that longjmp doesn't munge local
6101 struct jpeg_decompress_struct cinfo
;
6105 MY_JPEG_INVALID_IMAGE_SIZE
,
6106 MY_JPEG_CANNOT_CREATE_X
6114 static _Noreturn
void
6115 my_error_exit (j_common_ptr cinfo
)
6117 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
6118 mgr
->failure_code
= MY_JPEG_ERROR_EXIT
;
6119 sys_longjmp (mgr
->setjmp_buffer
, 1);
6123 /* Init source method for JPEG data source manager. Called by
6124 jpeg_read_header() before any data is actually read. See
6125 libjpeg.doc from the JPEG lib distribution. */
6128 our_common_init_source (j_decompress_ptr cinfo
)
6133 /* Method to terminate data source. Called by
6134 jpeg_finish_decompress() after all data has been processed. */
6137 our_common_term_source (j_decompress_ptr cinfo
)
6142 /* Fill input buffer method for JPEG data source manager. Called
6143 whenever more data is needed. We read the whole image in one step,
6144 so this only adds a fake end of input marker at the end. */
6146 static JOCTET our_memory_buffer
[2];
6149 our_memory_fill_input_buffer (j_decompress_ptr cinfo
)
6151 /* Insert a fake EOI marker. */
6152 struct jpeg_source_mgr
*src
= cinfo
->src
;
6154 our_memory_buffer
[0] = (JOCTET
) 0xFF;
6155 our_memory_buffer
[1] = (JOCTET
) JPEG_EOI
;
6157 src
->next_input_byte
= our_memory_buffer
;
6158 src
->bytes_in_buffer
= 2;
6163 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6164 is the JPEG data source manager. */
6167 our_memory_skip_input_data (j_decompress_ptr cinfo
, long int num_bytes
)
6169 struct jpeg_source_mgr
*src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6173 if (num_bytes
> src
->bytes_in_buffer
)
6174 ERREXIT (cinfo
, JERR_INPUT_EOF
);
6176 src
->bytes_in_buffer
-= num_bytes
;
6177 src
->next_input_byte
+= num_bytes
;
6182 /* Set up the JPEG lib for reading an image from DATA which contains
6183 LEN bytes. CINFO is the decompression info structure created for
6184 reading the image. */
6187 jpeg_memory_src (j_decompress_ptr cinfo
, JOCTET
*data
, ptrdiff_t len
)
6189 struct jpeg_source_mgr
*src
;
6191 if (cinfo
->src
== NULL
)
6193 /* First time for this JPEG object? */
6194 cinfo
->src
= (struct jpeg_source_mgr
*)
6195 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6196 sizeof (struct jpeg_source_mgr
));
6197 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6198 src
->next_input_byte
= data
;
6201 src
= (struct jpeg_source_mgr
*) cinfo
->src
;
6202 src
->init_source
= our_common_init_source
;
6203 src
->fill_input_buffer
= our_memory_fill_input_buffer
;
6204 src
->skip_input_data
= our_memory_skip_input_data
;
6205 src
->resync_to_restart
= jpeg_resync_to_restart_wrapper
; /* Use default method. */
6206 src
->term_source
= our_common_term_source
;
6207 src
->bytes_in_buffer
= len
;
6208 src
->next_input_byte
= data
;
6212 struct jpeg_stdio_mgr
6214 struct jpeg_source_mgr mgr
;
6221 /* Size of buffer to read JPEG from file.
6222 Not too big, as we want to use alloc_small. */
6223 #define JPEG_STDIO_BUFFER_SIZE 8192
6226 /* Fill input buffer method for JPEG data source manager. Called
6227 whenever more data is needed. The data is read from a FILE *. */
6230 our_stdio_fill_input_buffer (j_decompress_ptr cinfo
)
6232 struct jpeg_stdio_mgr
*src
;
6234 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6239 bytes
= fread (src
->buffer
, 1, JPEG_STDIO_BUFFER_SIZE
, src
->file
);
6241 src
->mgr
.bytes_in_buffer
= bytes
;
6244 WARNMS (cinfo
, JWRN_JPEG_EOF
);
6246 src
->buffer
[0] = (JOCTET
) 0xFF;
6247 src
->buffer
[1] = (JOCTET
) JPEG_EOI
;
6248 src
->mgr
.bytes_in_buffer
= 2;
6250 src
->mgr
.next_input_byte
= src
->buffer
;
6257 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6258 is the JPEG data source manager. */
6261 our_stdio_skip_input_data (j_decompress_ptr cinfo
, long int num_bytes
)
6263 struct jpeg_stdio_mgr
*src
;
6264 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6266 while (num_bytes
> 0 && !src
->finished
)
6268 if (num_bytes
<= src
->mgr
.bytes_in_buffer
)
6270 src
->mgr
.bytes_in_buffer
-= num_bytes
;
6271 src
->mgr
.next_input_byte
+= num_bytes
;
6276 num_bytes
-= src
->mgr
.bytes_in_buffer
;
6277 src
->mgr
.bytes_in_buffer
= 0;
6278 src
->mgr
.next_input_byte
= NULL
;
6280 our_stdio_fill_input_buffer (cinfo
);
6286 /* Set up the JPEG lib for reading an image from a FILE *.
6287 CINFO is the decompression info structure created for
6288 reading the image. */
6291 jpeg_file_src (j_decompress_ptr cinfo
, FILE *fp
)
6293 struct jpeg_stdio_mgr
*src
;
6295 if (cinfo
->src
!= NULL
)
6296 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6299 /* First time for this JPEG object? */
6300 cinfo
->src
= (struct jpeg_source_mgr
*)
6301 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6302 sizeof (struct jpeg_stdio_mgr
));
6303 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6304 src
->buffer
= (JOCTET
*)
6305 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_PERMANENT
,
6306 JPEG_STDIO_BUFFER_SIZE
);
6311 src
->mgr
.init_source
= our_common_init_source
;
6312 src
->mgr
.fill_input_buffer
= our_stdio_fill_input_buffer
;
6313 src
->mgr
.skip_input_data
= our_stdio_skip_input_data
;
6314 src
->mgr
.resync_to_restart
= jpeg_resync_to_restart_wrapper
; /* Use default method. */
6315 src
->mgr
.term_source
= our_common_term_source
;
6316 src
->mgr
.bytes_in_buffer
= 0;
6317 src
->mgr
.next_input_byte
= NULL
;
6321 /* Load image IMG for use on frame F. Patterned after example.c
6322 from the JPEG lib. */
6325 jpeg_load_body (struct frame
*f
, struct image
*img
,
6326 struct my_jpeg_error_mgr
*mgr
)
6328 Lisp_Object file
, specified_file
;
6329 Lisp_Object specified_data
;
6332 int row_stride
, x
, y
;
6333 XImagePtr ximg
= NULL
;
6334 unsigned long *colors
;
6337 /* Open the JPEG file. */
6338 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6339 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6341 if (NILP (specified_data
))
6343 file
= x_find_image_file (specified_file
);
6344 if (!STRINGP (file
))
6346 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6350 fp
= fopen (SSDATA (file
), "rb");
6353 image_error ("Cannot open `%s'", file
, Qnil
);
6357 else if (!STRINGP (specified_data
))
6359 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
6363 IF_LINT (mgr
->fp
= fp
);
6365 /* Customize libjpeg's error handling to call my_error_exit when an
6366 error is detected. This function will perform a longjmp. */
6367 mgr
->cinfo
.err
= fn_jpeg_std_error (&mgr
->pub
);
6368 mgr
->pub
.error_exit
= my_error_exit
;
6369 if (sys_setjmp (mgr
->setjmp_buffer
))
6371 switch (mgr
->failure_code
)
6373 case MY_JPEG_ERROR_EXIT
:
6375 char buf
[JMSG_LENGTH_MAX
];
6376 mgr
->cinfo
.err
->format_message ((j_common_ptr
) &mgr
->cinfo
, buf
);
6377 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
6378 build_string (buf
));
6382 case MY_JPEG_INVALID_IMAGE_SIZE
:
6383 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
6386 case MY_JPEG_CANNOT_CREATE_X
:
6390 /* Close the input file and destroy the JPEG object. */
6393 fn_jpeg_destroy_decompress (&mgr
->cinfo
);
6395 /* If we already have an XImage, free that. */
6396 x_destroy_x_image (ximg
);
6398 /* Free pixmap and colors. */
6399 x_clear_image (f
, img
);
6403 /* Silence a bogus diagnostic; see GCC bug 54561. */
6404 IF_LINT (fp
= mgr
->fp
);
6406 /* Create the JPEG decompression object. Let it read from fp.
6407 Read the JPEG image header. */
6408 fn_jpeg_CreateDecompress (&mgr
->cinfo
, JPEG_LIB_VERSION
, sizeof *&mgr
->cinfo
);
6410 if (NILP (specified_data
))
6411 jpeg_file_src (&mgr
->cinfo
, fp
);
6413 jpeg_memory_src (&mgr
->cinfo
, SDATA (specified_data
),
6414 SBYTES (specified_data
));
6416 fn_jpeg_read_header (&mgr
->cinfo
, 1);
6418 /* Customize decompression so that color quantization will be used.
6419 Start decompression. */
6420 mgr
->cinfo
.quantize_colors
= 1;
6421 fn_jpeg_start_decompress (&mgr
->cinfo
);
6422 width
= img
->width
= mgr
->cinfo
.output_width
;
6423 height
= img
->height
= mgr
->cinfo
.output_height
;
6425 if (!check_image_size (f
, width
, height
))
6427 mgr
->failure_code
= MY_JPEG_INVALID_IMAGE_SIZE
;
6428 sys_longjmp (mgr
->setjmp_buffer
, 1);
6431 /* Create X image and pixmap. */
6432 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
6434 mgr
->failure_code
= MY_JPEG_CANNOT_CREATE_X
;
6435 sys_longjmp (mgr
->setjmp_buffer
, 1);
6438 /* Allocate colors. When color quantization is used,
6439 mgr->cinfo.actual_number_of_colors has been set with the number of
6440 colors generated, and mgr->cinfo.colormap is a two-dimensional array
6441 of color indices in the range 0..mgr->cinfo.actual_number_of_colors.
6442 No more than 255 colors will be generated. */
6446 if (mgr
->cinfo
.out_color_components
> 2)
6447 ir
= 0, ig
= 1, ib
= 2;
6448 else if (mgr
->cinfo
.out_color_components
> 1)
6449 ir
= 0, ig
= 1, ib
= 0;
6451 ir
= 0, ig
= 0, ib
= 0;
6453 /* Use the color table mechanism because it handles colors that
6454 cannot be allocated nicely. Such colors will be replaced with
6455 a default color, and we don't have to care about which colors
6456 can be freed safely, and which can't. */
6457 init_color_table ();
6458 colors
= alloca (mgr
->cinfo
.actual_number_of_colors
* sizeof *colors
);
6460 for (i
= 0; i
< mgr
->cinfo
.actual_number_of_colors
; ++i
)
6462 /* Multiply RGB values with 255 because X expects RGB values
6463 in the range 0..0xffff. */
6464 int r
= mgr
->cinfo
.colormap
[ir
][i
] << 8;
6465 int g
= mgr
->cinfo
.colormap
[ig
][i
] << 8;
6466 int b
= mgr
->cinfo
.colormap
[ib
][i
] << 8;
6467 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
6470 #ifdef COLOR_TABLE_SUPPORT
6471 /* Remember those colors actually allocated. */
6472 img
->colors
= colors_in_color_table (&img
->ncolors
);
6473 free_color_table ();
6474 #endif /* COLOR_TABLE_SUPPORT */
6478 row_stride
= width
* mgr
->cinfo
.output_components
;
6479 buffer
= mgr
->cinfo
.mem
->alloc_sarray ((j_common_ptr
) &mgr
->cinfo
,
6480 JPOOL_IMAGE
, row_stride
, 1);
6481 for (y
= 0; y
< height
; ++y
)
6483 fn_jpeg_read_scanlines (&mgr
->cinfo
, buffer
, 1);
6484 for (x
= 0; x
< mgr
->cinfo
.output_width
; ++x
)
6485 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
6489 fn_jpeg_finish_decompress (&mgr
->cinfo
);
6490 fn_jpeg_destroy_decompress (&mgr
->cinfo
);
6494 /* Maybe fill in the background field while we have ximg handy. */
6495 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6496 /* Casting avoids a GCC warning. */
6497 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6499 /* Put the image into the pixmap. */
6500 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6501 x_destroy_x_image (ximg
);
6506 jpeg_load (struct frame
*f
, struct image
*img
)
6508 struct my_jpeg_error_mgr mgr
;
6509 return jpeg_load_body (f
, img
, &mgr
);
6512 #else /* HAVE_JPEG */
6516 jpeg_load (struct frame
*f
, struct image
*img
)
6518 return ns_load_image (f
, img
,
6519 image_spec_value (img
->spec
, QCfile
, NULL
),
6520 image_spec_value (img
->spec
, QCdata
, NULL
));
6522 #endif /* HAVE_NS */
6524 #endif /* !HAVE_JPEG */
6528 /***********************************************************************
6530 ***********************************************************************/
6532 #if defined (HAVE_TIFF) || defined (HAVE_NS)
6534 static bool tiff_image_p (Lisp_Object object
);
6535 static bool tiff_load (struct frame
*f
, struct image
*img
);
6537 /* The symbol `tiff' identifying images of this type. */
6539 static Lisp_Object Qtiff
;
6541 /* Indices of image specification fields in tiff_format, below. */
6543 enum tiff_keyword_index
6552 TIFF_HEURISTIC_MASK
,
6559 /* Vector of image_keyword structures describing the format
6560 of valid user-defined image specifications. */
6562 static const struct image_keyword tiff_format
[TIFF_LAST
] =
6564 {":type", IMAGE_SYMBOL_VALUE
, 1},
6565 {":data", IMAGE_STRING_VALUE
, 0},
6566 {":file", IMAGE_STRING_VALUE
, 0},
6567 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6568 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
6569 {":relief", IMAGE_INTEGER_VALUE
, 0},
6570 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6571 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6572 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6573 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
6574 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0}
6577 #if defined HAVE_NTGUI && defined WINDOWSNT
6578 static bool init_tiff_functions (void);
6580 #define init_tiff_functions NULL
6583 /* Structure describing the image type `tiff'. */
6585 static struct image_type tiff_type
=
6591 init_tiff_functions
,
6595 /* Return true if OBJECT is a valid TIFF image specification. */
6598 tiff_image_p (Lisp_Object object
)
6600 struct image_keyword fmt
[TIFF_LAST
];
6601 memcpy (fmt
, tiff_format
, sizeof fmt
);
6603 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
6606 /* Must specify either the :data or :file keyword. */
6607 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
6610 #endif /* HAVE_TIFF || HAVE_NS */
6618 /* TIFF library details. */
6619 DEF_IMGLIB_FN (TIFFErrorHandler
, TIFFSetErrorHandler
, (TIFFErrorHandler
));
6620 DEF_IMGLIB_FN (TIFFErrorHandler
, TIFFSetWarningHandler
, (TIFFErrorHandler
));
6621 DEF_IMGLIB_FN (TIFF
*, TIFFOpen
, (const char *, const char *));
6622 DEF_IMGLIB_FN (TIFF
*, TIFFClientOpen
, (const char *, const char *, thandle_t
,
6623 TIFFReadWriteProc
, TIFFReadWriteProc
,
6624 TIFFSeekProc
, TIFFCloseProc
, TIFFSizeProc
,
6625 TIFFMapFileProc
, TIFFUnmapFileProc
));
6626 DEF_IMGLIB_FN (int, TIFFGetField
, (TIFF
*, ttag_t
, ...));
6627 DEF_IMGLIB_FN (int, TIFFReadRGBAImage
, (TIFF
*, uint32
, uint32
, uint32
*, int));
6628 DEF_IMGLIB_FN (void, TIFFClose
, (TIFF
*));
6629 DEF_IMGLIB_FN (int, TIFFSetDirectory
, (TIFF
*, tdir_t
));
6632 init_tiff_functions (void)
6636 if (!(library
= w32_delayed_load (Qtiff
)))
6639 LOAD_IMGLIB_FN (library
, TIFFSetErrorHandler
);
6640 LOAD_IMGLIB_FN (library
, TIFFSetWarningHandler
);
6641 LOAD_IMGLIB_FN (library
, TIFFOpen
);
6642 LOAD_IMGLIB_FN (library
, TIFFClientOpen
);
6643 LOAD_IMGLIB_FN (library
, TIFFGetField
);
6644 LOAD_IMGLIB_FN (library
, TIFFReadRGBAImage
);
6645 LOAD_IMGLIB_FN (library
, TIFFClose
);
6646 LOAD_IMGLIB_FN (library
, TIFFSetDirectory
);
6652 #define fn_TIFFSetErrorHandler TIFFSetErrorHandler
6653 #define fn_TIFFSetWarningHandler TIFFSetWarningHandler
6654 #define fn_TIFFOpen TIFFOpen
6655 #define fn_TIFFClientOpen TIFFClientOpen
6656 #define fn_TIFFGetField TIFFGetField
6657 #define fn_TIFFReadRGBAImage TIFFReadRGBAImage
6658 #define fn_TIFFClose TIFFClose
6659 #define fn_TIFFSetDirectory TIFFSetDirectory
6660 #endif /* WINDOWSNT */
6663 /* Reading from a memory buffer for TIFF images Based on the PNG
6664 memory source, but we have to provide a lot of extra functions.
6667 We really only need to implement read and seek, but I am not
6668 convinced that the TIFF library is smart enough not to destroy
6669 itself if we only hand it the function pointers we need to
6674 unsigned char *bytes
;
6681 tiff_read_from_memory (thandle_t data
, tdata_t buf
, tsize_t size
)
6683 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6685 size
= min (size
, src
->len
- src
->index
);
6686 memcpy (buf
, src
->bytes
+ src
->index
, size
);
6692 tiff_write_from_memory (thandle_t data
, tdata_t buf
, tsize_t size
)
6698 tiff_seek_in_memory (thandle_t data
, toff_t off
, int whence
)
6700 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6705 case SEEK_SET
: /* Go from beginning of source. */
6709 case SEEK_END
: /* Go from end of source. */
6710 idx
= src
->len
+ off
;
6713 case SEEK_CUR
: /* Go from current position. */
6714 idx
= src
->index
+ off
;
6717 default: /* Invalid `whence'. */
6721 if (idx
> src
->len
|| idx
< 0)
6729 tiff_close_memory (thandle_t data
)
6736 tiff_mmap_memory (thandle_t data
, tdata_t
*pbase
, toff_t
*psize
)
6738 /* It is already _IN_ memory. */
6743 tiff_unmap_memory (thandle_t data
, tdata_t base
, toff_t size
)
6745 /* We don't need to do this. */
6749 tiff_size_of_memory (thandle_t data
)
6751 return ((tiff_memory_source
*) data
)->len
;
6754 /* GCC 3.x on x86 Windows targets has a bug that triggers an internal
6755 compiler error compiling tiff_handler, see Bugzilla bug #17406
6756 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17406). Declaring
6757 this function as external works around that problem. */
6758 #if defined (__MINGW32__) && __GNUC__ == 3
6759 # define MINGW_STATIC
6761 # define MINGW_STATIC static
6765 tiff_handler (const char *, const char *, const char *, va_list)
6766 ATTRIBUTE_FORMAT_PRINTF (3, 0);
6768 tiff_handler (const char *log_format
, const char *title
,
6769 const char *format
, va_list ap
)
6771 /* doprnt is not suitable here, as TIFF handlers are called from
6772 libtiff and are passed arbitrary printf directives. Instead, use
6773 vsnprintf, taking care to be portable to nonstandard environments
6774 where vsnprintf returns -1 on buffer overflow. Since it's just a
6775 log entry, it's OK to truncate it. */
6777 int len
= vsnprintf (buf
, sizeof buf
, format
, ap
);
6778 add_to_log (log_format
, build_string (title
),
6779 make_string (buf
, max (0, min (len
, sizeof buf
- 1))));
6783 static void tiff_error_handler (const char *, const char *, va_list)
6784 ATTRIBUTE_FORMAT_PRINTF (2, 0);
6786 tiff_error_handler (const char *title
, const char *format
, va_list ap
)
6788 tiff_handler ("TIFF error: %s %s", title
, format
, ap
);
6792 static void tiff_warning_handler (const char *, const char *, va_list)
6793 ATTRIBUTE_FORMAT_PRINTF (2, 0);
6795 tiff_warning_handler (const char *title
, const char *format
, va_list ap
)
6797 tiff_handler ("TIFF warning: %s %s", title
, format
, ap
);
6801 /* Load TIFF image IMG for use on frame F. Value is true if
6805 tiff_load (struct frame
*f
, struct image
*img
)
6807 Lisp_Object file
, specified_file
;
6808 Lisp_Object specified_data
;
6810 int width
, height
, x
, y
, count
;
6814 tiff_memory_source memsrc
;
6817 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6818 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6820 fn_TIFFSetErrorHandler ((TIFFErrorHandler
) tiff_error_handler
);
6821 fn_TIFFSetWarningHandler ((TIFFErrorHandler
) tiff_warning_handler
);
6823 if (NILP (specified_data
))
6825 /* Read from a file */
6826 file
= x_find_image_file (specified_file
);
6827 if (!STRINGP (file
))
6829 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6833 /* Try to open the image file. */
6834 tiff
= fn_TIFFOpen (SSDATA (file
), "r");
6837 image_error ("Cannot open `%s'", file
, Qnil
);
6843 if (!STRINGP (specified_data
))
6845 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
6849 /* Memory source! */
6850 memsrc
.bytes
= SDATA (specified_data
);
6851 memsrc
.len
= SBYTES (specified_data
);
6854 tiff
= fn_TIFFClientOpen ("memory_source", "r", (thandle_t
)&memsrc
,
6855 tiff_read_from_memory
,
6856 tiff_write_from_memory
,
6857 tiff_seek_in_memory
,
6859 tiff_size_of_memory
,
6865 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
6870 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
6871 if (INTEGERP (image
))
6873 EMACS_INT ino
= XFASTINT (image
);
6874 if (! (TYPE_MINIMUM (tdir_t
) <= ino
&& ino
<= TYPE_MAXIMUM (tdir_t
)
6875 && fn_TIFFSetDirectory (tiff
, ino
)))
6877 image_error ("Invalid image number `%s' in image `%s'",
6879 fn_TIFFClose (tiff
);
6884 /* Get width and height of the image, and allocate a raster buffer
6885 of width x height 32-bit values. */
6886 fn_TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
6887 fn_TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
6889 if (!check_image_size (f
, width
, height
))
6891 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
6892 fn_TIFFClose (tiff
);
6896 /* Create the X image and pixmap. */
6897 if (! (height
<= min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *buf
/ width
6898 && x_create_x_image_and_pixmap (f
, width
, height
, 0,
6899 &ximg
, &img
->pixmap
)))
6901 fn_TIFFClose (tiff
);
6905 buf
= xmalloc (sizeof *buf
* width
* height
);
6907 rc
= fn_TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
6909 /* Count the number of images in the file. */
6910 for (count
= 1; fn_TIFFSetDirectory (tiff
, count
); count
++)
6914 img
->lisp_data
= Fcons (Qcount
,
6915 Fcons (make_number (count
),
6918 fn_TIFFClose (tiff
);
6921 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
6926 /* Initialize the color table. */
6927 init_color_table ();
6929 /* Process the pixel raster. Origin is in the lower-left corner. */
6930 for (y
= 0; y
< height
; ++y
)
6932 uint32
*row
= buf
+ y
* width
;
6934 for (x
= 0; x
< width
; ++x
)
6936 uint32 abgr
= row
[x
];
6937 int r
= TIFFGetR (abgr
) << 8;
6938 int g
= TIFFGetG (abgr
) << 8;
6939 int b
= TIFFGetB (abgr
) << 8;
6940 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
6944 #ifdef COLOR_TABLE_SUPPORT
6945 /* Remember the colors allocated for the image. Free the color table. */
6946 img
->colors
= colors_in_color_table (&img
->ncolors
);
6947 free_color_table ();
6948 #endif /* COLOR_TABLE_SUPPORT */
6951 img
->height
= height
;
6953 /* Maybe fill in the background field while we have ximg handy. */
6954 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6955 /* Casting avoids a GCC warning on W32. */
6956 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6958 /* Put the image into the pixmap, then free the X image and its buffer. */
6959 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
6960 x_destroy_x_image (ximg
);
6966 #else /* HAVE_TIFF */
6970 tiff_load (struct frame
*f
, struct image
*img
)
6972 return ns_load_image (f
, img
,
6973 image_spec_value (img
->spec
, QCfile
, NULL
),
6974 image_spec_value (img
->spec
, QCdata
, NULL
));
6976 #endif /* HAVE_NS */
6978 #endif /* !HAVE_TIFF */
6982 /***********************************************************************
6984 ***********************************************************************/
6986 #if defined (HAVE_GIF) || defined (HAVE_NS)
6988 static bool gif_image_p (Lisp_Object object
);
6989 static bool gif_load (struct frame
*f
, struct image
*img
);
6990 static void gif_clear_image (struct frame
*f
, struct image
*img
);
6992 /* The symbol `gif' identifying images of this type. */
6994 static Lisp_Object Qgif
;
6996 /* Indices of image specification fields in gif_format, below. */
6998 enum gif_keyword_index
7014 /* Vector of image_keyword structures describing the format
7015 of valid user-defined image specifications. */
7017 static const struct image_keyword gif_format
[GIF_LAST
] =
7019 {":type", IMAGE_SYMBOL_VALUE
, 1},
7020 {":data", IMAGE_STRING_VALUE
, 0},
7021 {":file", IMAGE_STRING_VALUE
, 0},
7022 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7023 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
7024 {":relief", IMAGE_INTEGER_VALUE
, 0},
7025 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7026 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7027 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7028 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7029 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7032 #if defined HAVE_NTGUI && defined WINDOWSNT
7033 static bool init_gif_functions (void);
7035 #define init_gif_functions NULL
7038 /* Structure describing the image type `gif'. */
7040 static struct image_type gif_type
=
7050 /* Free X resources of GIF image IMG which is used on frame F. */
7053 gif_clear_image (struct frame
*f
, struct image
*img
)
7055 img
->lisp_data
= Qnil
;
7056 x_clear_image (f
, img
);
7059 /* Return true if OBJECT is a valid GIF image specification. */
7062 gif_image_p (Lisp_Object object
)
7064 struct image_keyword fmt
[GIF_LAST
];
7065 memcpy (fmt
, gif_format
, sizeof fmt
);
7067 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
7070 /* Must specify either the :data or :file keyword. */
7071 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
7074 #endif /* HAVE_GIF */
7078 #if defined (HAVE_NTGUI)
7079 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
7080 Undefine before redefining to avoid a preprocessor warning. */
7084 /* avoid conflict with QuickdrawText.h */
7085 #define DrawText gif_DrawText
7086 #include <gif_lib.h>
7089 #else /* HAVE_NTGUI */
7091 #include <gif_lib.h>
7093 #endif /* HAVE_NTGUI */
7098 /* GIF library details. */
7099 DEF_IMGLIB_FN (int, DGifCloseFile
, (GifFileType
*));
7100 DEF_IMGLIB_FN (int, DGifSlurp
, (GifFileType
*));
7101 DEF_IMGLIB_FN (GifFileType
*, DGifOpen
, (void *, InputFunc
));
7102 DEF_IMGLIB_FN (GifFileType
*, DGifOpenFileName
, (const char *));
7105 init_gif_functions (void)
7109 if (!(library
= w32_delayed_load (Qgif
)))
7112 LOAD_IMGLIB_FN (library
, DGifCloseFile
);
7113 LOAD_IMGLIB_FN (library
, DGifSlurp
);
7114 LOAD_IMGLIB_FN (library
, DGifOpen
);
7115 LOAD_IMGLIB_FN (library
, DGifOpenFileName
);
7121 #define fn_DGifCloseFile DGifCloseFile
7122 #define fn_DGifSlurp DGifSlurp
7123 #define fn_DGifOpen DGifOpen
7124 #define fn_DGifOpenFileName DGifOpenFileName
7126 #endif /* WINDOWSNT */
7128 /* Reading a GIF image from memory
7129 Based on the PNG memory stuff to a certain extent. */
7133 unsigned char *bytes
;
7139 /* Make the current memory source available to gif_read_from_memory.
7140 It's done this way because not all versions of libungif support
7141 a UserData field in the GifFileType structure. */
7142 static gif_memory_source
*current_gif_memory_src
;
7145 gif_read_from_memory (GifFileType
*file
, GifByteType
*buf
, int len
)
7147 gif_memory_source
*src
= current_gif_memory_src
;
7149 if (len
> src
->len
- src
->index
)
7152 memcpy (buf
, src
->bytes
+ src
->index
, len
);
7158 /* Load GIF image IMG for use on frame F. Value is true if
7161 static const int interlace_start
[] = {0, 4, 2, 1};
7162 static const int interlace_increment
[] = {8, 8, 4, 2};
7164 #define GIF_LOCAL_DESCRIPTOR_EXTENSION 249
7167 gif_load (struct frame
*f
, struct image
*img
)
7170 int rc
, width
, height
, x
, y
, i
, j
;
7172 ColorMapObject
*gif_color_map
;
7173 unsigned long pixel_colors
[256];
7175 gif_memory_source memsrc
;
7176 Lisp_Object specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
7177 Lisp_Object specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7178 Lisp_Object specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7179 unsigned long bgcolor
= 0;
7182 if (NILP (specified_data
))
7184 file
= x_find_image_file (specified_file
);
7185 if (!STRINGP (file
))
7187 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7191 /* Open the GIF file. */
7192 gif
= fn_DGifOpenFileName (SSDATA (file
));
7195 image_error ("Cannot open `%s'", file
, Qnil
);
7201 if (!STRINGP (specified_data
))
7203 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
7207 /* Read from memory! */
7208 current_gif_memory_src
= &memsrc
;
7209 memsrc
.bytes
= SDATA (specified_data
);
7210 memsrc
.len
= SBYTES (specified_data
);
7213 gif
= fn_DGifOpen (&memsrc
, gif_read_from_memory
);
7216 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
7221 /* Before reading entire contents, check the declared image size. */
7222 if (!check_image_size (f
, gif
->SWidth
, gif
->SHeight
))
7224 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7225 fn_DGifCloseFile (gif
);
7229 /* Read entire contents. */
7230 rc
= fn_DGifSlurp (gif
);
7231 if (rc
== GIF_ERROR
|| gif
->ImageCount
<= 0)
7233 image_error ("Error reading `%s'", img
->spec
, Qnil
);
7234 fn_DGifCloseFile (gif
);
7238 /* Which sub-image are we to display? */
7240 Lisp_Object image_number
= image_spec_value (img
->spec
, QCindex
, NULL
);
7241 idx
= INTEGERP (image_number
) ? XFASTINT (image_number
) : 0;
7242 if (idx
< 0 || idx
>= gif
->ImageCount
)
7244 image_error ("Invalid image number `%s' in image `%s'",
7245 image_number
, img
->spec
);
7246 fn_DGifCloseFile (gif
);
7251 width
= img
->width
= gif
->SWidth
;
7252 height
= img
->height
= gif
->SHeight
;
7254 img
->corners
[TOP_CORNER
] = gif
->SavedImages
[0].ImageDesc
.Top
;
7255 img
->corners
[LEFT_CORNER
] = gif
->SavedImages
[0].ImageDesc
.Left
;
7256 img
->corners
[BOT_CORNER
]
7257 = img
->corners
[TOP_CORNER
] + gif
->SavedImages
[0].ImageDesc
.Height
;
7258 img
->corners
[RIGHT_CORNER
]
7259 = img
->corners
[LEFT_CORNER
] + gif
->SavedImages
[0].ImageDesc
.Width
;
7261 if (!check_image_size (f
, width
, height
))
7263 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7264 fn_DGifCloseFile (gif
);
7268 /* Check that the selected subimages fit. It's not clear whether
7269 the GIF spec requires this, but Emacs can crash if they don't fit. */
7270 for (j
= 0; j
<= idx
; ++j
)
7272 struct SavedImage
*subimage
= gif
->SavedImages
+ j
;
7273 int subimg_width
= subimage
->ImageDesc
.Width
;
7274 int subimg_height
= subimage
->ImageDesc
.Height
;
7275 int subimg_top
= subimage
->ImageDesc
.Top
;
7276 int subimg_left
= subimage
->ImageDesc
.Left
;
7277 if (! (0 <= subimg_width
&& 0 <= subimg_height
7278 && 0 <= subimg_top
&& subimg_top
<= height
- subimg_height
7279 && 0 <= subimg_left
&& subimg_left
<= width
- subimg_width
))
7281 image_error ("Subimage does not fit in image", Qnil
, Qnil
);
7282 fn_DGifCloseFile (gif
);
7287 /* Create the X image and pixmap. */
7288 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
7290 fn_DGifCloseFile (gif
);
7294 /* Clear the part of the screen image not covered by the image.
7295 Full animated GIF support requires more here (see the gif89 spec,
7296 disposal methods). Let's simply assume that the part not covered
7297 by a sub-image is in the frame's background color. */
7298 for (y
= 0; y
< img
->corners
[TOP_CORNER
]; ++y
)
7299 for (x
= 0; x
< width
; ++x
)
7300 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7302 for (y
= img
->corners
[BOT_CORNER
]; y
< height
; ++y
)
7303 for (x
= 0; x
< width
; ++x
)
7304 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7306 for (y
= img
->corners
[TOP_CORNER
]; y
< img
->corners
[BOT_CORNER
]; ++y
)
7308 for (x
= 0; x
< img
->corners
[LEFT_CORNER
]; ++x
)
7309 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7310 for (x
= img
->corners
[RIGHT_CORNER
]; x
< width
; ++x
)
7311 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7314 /* Read the GIF image into the X image. */
7316 /* FIXME: With the current implementation, loading an animated gif
7317 is quadratic in the number of animation frames, since each frame
7318 is a separate struct image. We must provide a way for a single
7319 gif_load call to construct and save all animation frames. */
7321 init_color_table ();
7322 if (STRINGP (specified_bg
))
7323 bgcolor
= x_alloc_image_color (f
, img
, specified_bg
,
7324 FRAME_BACKGROUND_PIXEL (f
));
7325 for (j
= 0; j
<= idx
; ++j
)
7327 /* We use a local variable `raster' here because RasterBits is a
7328 char *, which invites problems with bytes >= 0x80. */
7329 struct SavedImage
*subimage
= gif
->SavedImages
+ j
;
7330 unsigned char *raster
= (unsigned char *) subimage
->RasterBits
;
7331 int transparency_color_index
= -1;
7333 int subimg_width
= subimage
->ImageDesc
.Width
;
7334 int subimg_height
= subimage
->ImageDesc
.Height
;
7335 int subimg_top
= subimage
->ImageDesc
.Top
;
7336 int subimg_left
= subimage
->ImageDesc
.Left
;
7338 /* Find the Graphic Control Extension block for this sub-image.
7339 Extract the disposal method and transparency color. */
7340 for (i
= 0; i
< subimage
->ExtensionBlockCount
; i
++)
7342 ExtensionBlock
*extblock
= subimage
->ExtensionBlocks
+ i
;
7344 if ((extblock
->Function
== GIF_LOCAL_DESCRIPTOR_EXTENSION
)
7345 && extblock
->ByteCount
== 4
7346 && extblock
->Bytes
[0] & 1)
7348 /* From gif89a spec: 1 = "keep in place", 2 = "restore
7349 to background". Treat any other value like 2. */
7350 disposal
= (extblock
->Bytes
[0] >> 2) & 7;
7351 transparency_color_index
= (unsigned char) extblock
->Bytes
[3];
7356 /* We can't "keep in place" the first subimage. */
7360 /* For disposal == 0, the spec says "No disposal specified. The
7361 decoder is not required to take any action." In practice, it
7362 seems we need to treat this like "keep in place", see e.g.
7363 http://upload.wikimedia.org/wikipedia/commons/3/37/Clock.gif */
7367 /* Allocate subimage colors. */
7368 memset (pixel_colors
, 0, sizeof pixel_colors
);
7369 gif_color_map
= subimage
->ImageDesc
.ColorMap
;
7371 gif_color_map
= gif
->SColorMap
;
7374 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
7376 if (transparency_color_index
== i
)
7377 pixel_colors
[i
] = STRINGP (specified_bg
)
7378 ? bgcolor
: FRAME_BACKGROUND_PIXEL (f
);
7381 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
7382 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
7383 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
7384 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
7388 /* Apply the pixel values. */
7389 if (gif
->SavedImages
[j
].ImageDesc
.Interlace
)
7393 for (y
= 0, row
= interlace_start
[0], pass
= 0;
7395 y
++, row
+= interlace_increment
[pass
])
7397 while (subimg_height
<= row
)
7399 lint_assume (pass
< 3);
7400 row
= interlace_start
[++pass
];
7403 for (x
= 0; x
< subimg_width
; x
++)
7405 int c
= raster
[y
* subimg_width
+ x
];
7406 if (transparency_color_index
!= c
|| disposal
!= 1)
7407 XPutPixel (ximg
, x
+ subimg_left
, row
+ subimg_top
,
7414 for (y
= 0; y
< subimg_height
; ++y
)
7415 for (x
= 0; x
< subimg_width
; ++x
)
7417 int c
= raster
[y
* subimg_width
+ x
];
7418 if (transparency_color_index
!= c
|| disposal
!= 1)
7419 XPutPixel (ximg
, x
+ subimg_left
, y
+ subimg_top
,
7425 #ifdef COLOR_TABLE_SUPPORT
7426 img
->colors
= colors_in_color_table (&img
->ncolors
);
7427 free_color_table ();
7428 #endif /* COLOR_TABLE_SUPPORT */
7430 /* Save GIF image extension data for `image-metadata'.
7431 Format is (count IMAGES extension-data (FUNCTION "BYTES" ...)). */
7432 img
->lisp_data
= Qnil
;
7433 if (gif
->SavedImages
[idx
].ExtensionBlockCount
> 0)
7436 ExtensionBlock
*ext
= gif
->SavedImages
[idx
].ExtensionBlocks
;
7437 for (i
= 0; i
< gif
->SavedImages
[idx
].ExtensionBlockCount
; i
++, ext
++)
7438 /* Append (... FUNCTION "BYTES") */
7441 = Fcons (make_number (ext
->Function
),
7442 Fcons (make_unibyte_string (ext
->Bytes
, ext
->ByteCount
),
7444 if (ext
->Function
== GIF_LOCAL_DESCRIPTOR_EXTENSION
7445 && ext
->ByteCount
== 4)
7447 delay
= ext
->Bytes
[2] << CHAR_BIT
;
7448 delay
|= ext
->Bytes
[1];
7451 img
->lisp_data
= Fcons (Qextension_data
,
7452 Fcons (img
->lisp_data
, Qnil
));
7456 Fcons (make_float (delay
/ 100.0),
7460 if (gif
->ImageCount
> 1)
7461 img
->lisp_data
= Fcons (Qcount
,
7462 Fcons (make_number (gif
->ImageCount
),
7465 fn_DGifCloseFile (gif
);
7467 /* Maybe fill in the background field while we have ximg handy. */
7468 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7469 /* Casting avoids a GCC warning. */
7470 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
7472 /* Put the image into the pixmap, then free the X image and its buffer. */
7473 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
7474 x_destroy_x_image (ximg
);
7479 #else /* !HAVE_GIF */
7483 gif_load (struct frame
*f
, struct image
*img
)
7485 return ns_load_image (f
, img
,
7486 image_spec_value (img
->spec
, QCfile
, NULL
),
7487 image_spec_value (img
->spec
, QCdata
, NULL
));
7489 #endif /* HAVE_NS */
7491 #endif /* HAVE_GIF */
7495 compute_image_size (size_t width
, size_t height
,
7497 int *d_width
, int *d_height
)
7500 int desired_width
, desired_height
;
7502 /* If width and/or height is set in the display spec assume we want
7503 to scale to those values. If either h or w is unspecified, the
7504 unspecified should be calculated from the specified to preserve
7506 value
= image_spec_value (spec
, QCwidth
, NULL
);
7507 desired_width
= (INTEGERP (value
) ? XFASTINT (value
) : -1);
7508 value
= image_spec_value (spec
, QCheight
, NULL
);
7509 desired_height
= (INTEGERP (value
) ? XFASTINT (value
) : -1);
7511 if (desired_width
== -1)
7513 value
= image_spec_value (spec
, QCmax_width
, NULL
);
7514 if (INTEGERP (value
) &&
7515 width
> XFASTINT (value
))
7517 /* The image is wider than :max-width. */
7518 desired_width
= XFASTINT (value
);
7519 if (desired_height
== -1)
7521 value
= image_spec_value (spec
, QCmax_height
, NULL
);
7522 if (INTEGERP (value
))
7524 /* We have no specified height, but we have a
7525 :max-height value, so check that we satisfy both
7527 desired_height
= (double) desired_width
/ width
* height
;
7528 if (desired_height
> XFASTINT (value
))
7530 desired_height
= XFASTINT (value
);
7531 desired_width
= (double) desired_height
/ height
* width
;
7536 /* We have no specified height and no specified
7537 max-height, so just compute the height. */
7538 desired_height
= (double) desired_width
/ width
* height
;
7544 if (desired_height
== -1)
7546 value
= image_spec_value (spec
, QCmax_height
, NULL
);
7547 if (INTEGERP (value
) &&
7548 height
> XFASTINT (value
))
7549 desired_height
= XFASTINT (value
);
7552 if (desired_width
!= -1 && desired_height
== -1)
7553 /* w known, calculate h. */
7554 desired_height
= (double) desired_width
/ width
* height
;
7556 if (desired_width
== -1 && desired_height
!= -1)
7557 /* h known, calculate w. */
7558 desired_width
= (double) desired_height
/ height
* width
;
7560 *d_width
= desired_width
;
7561 *d_height
= desired_height
;
7564 /***********************************************************************
7566 ***********************************************************************/
7567 #if defined (HAVE_IMAGEMAGICK)
7569 static Lisp_Object Qimagemagick
;
7571 static bool imagemagick_image_p (Lisp_Object
);
7572 static bool imagemagick_load (struct frame
*, struct image
*);
7573 static void imagemagick_clear_image (struct frame
*, struct image
*);
7575 /* Indices of image specification fields in imagemagick_format. */
7577 enum imagemagick_keyword_index
7585 IMAGEMAGICK_ALGORITHM
,
7586 IMAGEMAGICK_HEURISTIC_MASK
,
7588 IMAGEMAGICK_BACKGROUND
,
7591 IMAGEMAGICK_MAX_HEIGHT
,
7592 IMAGEMAGICK_MAX_WIDTH
,
7593 IMAGEMAGICK_ROTATION
,
7598 /* Vector of image_keyword structures describing the format
7599 of valid user-defined image specifications. */
7601 static struct image_keyword imagemagick_format
[IMAGEMAGICK_LAST
] =
7603 {":type", IMAGE_SYMBOL_VALUE
, 1},
7604 {":data", IMAGE_STRING_VALUE
, 0},
7605 {":file", IMAGE_STRING_VALUE
, 0},
7606 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7607 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
7608 {":relief", IMAGE_INTEGER_VALUE
, 0},
7609 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7610 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7611 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7612 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
7613 {":height", IMAGE_INTEGER_VALUE
, 0},
7614 {":width", IMAGE_INTEGER_VALUE
, 0},
7615 {":max-height", IMAGE_INTEGER_VALUE
, 0},
7616 {":max-width", IMAGE_INTEGER_VALUE
, 0},
7617 {":rotation", IMAGE_NUMBER_VALUE
, 0},
7618 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
7621 #if defined HAVE_NTGUI && defined WINDOWSNT
7622 static bool init_imagemagick_functions (void);
7624 #define init_imagemagick_functions NULL
7627 /* Structure describing the image type for any image handled via
7630 static struct image_type imagemagick_type
=
7633 imagemagick_image_p
,
7635 imagemagick_clear_image
,
7636 init_imagemagick_functions
,
7640 /* Free X resources of imagemagick image IMG which is used on frame F. */
7643 imagemagick_clear_image (struct frame
*f
,
7646 x_clear_image (f
, img
);
7649 /* Return true if OBJECT is a valid IMAGEMAGICK image specification. Do
7650 this by calling parse_image_spec and supplying the keywords that
7651 identify the IMAGEMAGICK format. */
7654 imagemagick_image_p (Lisp_Object object
)
7656 struct image_keyword fmt
[IMAGEMAGICK_LAST
];
7657 memcpy (fmt
, imagemagick_format
, sizeof fmt
);
7659 if (!parse_image_spec (object
, fmt
, IMAGEMAGICK_LAST
, Qimagemagick
))
7662 /* Must specify either the :data or :file keyword. */
7663 return fmt
[IMAGEMAGICK_FILE
].count
+ fmt
[IMAGEMAGICK_DATA
].count
== 1;
7666 /* The GIF library also defines DrawRectangle, but its never used in Emacs.
7667 Therefore rename the function so it doesn't collide with ImageMagick. */
7668 #define DrawRectangle DrawRectangleGif
7669 #include <wand/MagickWand.h>
7671 /* ImageMagick 6.5.3 through 6.6.5 hid PixelGetMagickColor for some reason.
7672 Emacs seems to work fine with the hidden version, so unhide it. */
7673 #include <magick/version.h>
7674 #if 0x653 <= MagickLibVersion && MagickLibVersion <= 0x665
7675 extern WandExport
void PixelGetMagickColor (const PixelWand
*,
7676 MagickPixelPacket
*);
7679 /* Log ImageMagick error message.
7680 Useful when a ImageMagick function returns the status `MagickFalse'. */
7683 imagemagick_error (MagickWand
*wand
)
7686 ExceptionType severity
;
7688 description
= MagickGetException (wand
, &severity
);
7689 image_error ("ImageMagick error: %s",
7690 build_string (description
),
7692 description
= (char *) MagickRelinquishMemory (description
);
7695 /* Helper function for imagemagick_load, which does the actual loading
7696 given contents and size, apart from frame and image structures,
7697 passed from imagemagick_load. Uses librimagemagick to do most of
7698 the image processing.
7700 F is a pointer to the Emacs frame; IMG to the image structure to
7701 prepare; CONTENTS is the string containing the IMAGEMAGICK data to
7702 be parsed; SIZE is the number of bytes of data; and FILENAME is
7703 either the file name or the image data.
7705 Return true if successful. */
7708 imagemagick_load_image (struct frame
*f
, struct image
*img
,
7709 unsigned char *contents
, unsigned int size
,
7712 size_t width
, height
;
7713 MagickBooleanType status
;
7716 MagickWand
*image_wand
;
7717 MagickWand
*ping_wand
;
7718 PixelIterator
*iterator
;
7719 PixelWand
**pixels
, *bg_wand
= NULL
;
7720 MagickPixelPacket pixel
;
7725 int desired_width
, desired_height
;
7729 /* Handle image index for image types who can contain more than one image.
7730 Interface :index is same as for GIF. First we "ping" the image to see how
7731 many sub-images it contains. Pinging is faster than loading the image to
7732 find out things about it. */
7734 /* Initialize the imagemagick environment. */
7735 MagickWandGenesis ();
7736 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
7737 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
7738 ping_wand
= NewMagickWand ();
7739 /* MagickSetResolution (ping_wand, 2, 2); (Bug#10112) */
7742 ? MagickPingImage (ping_wand
, filename
)
7743 : MagickPingImageBlob (ping_wand
, contents
, size
);
7745 if (status
== MagickFalse
)
7747 imagemagick_error (ping_wand
);
7748 DestroyMagickWand (ping_wand
);
7752 if (ino
< 0 || ino
>= MagickGetNumberImages (ping_wand
))
7754 image_error ("Invalid image number `%s' in image `%s'",
7756 DestroyMagickWand (ping_wand
);
7760 if (MagickGetNumberImages (ping_wand
) > 1)
7763 Fcons (make_number (MagickGetNumberImages (ping_wand
)),
7766 DestroyMagickWand (ping_wand
);
7768 /* Now we know how many images are inside the file. If it's not a
7769 bundle, the number is one. Load the image data. */
7771 image_wand
= NewMagickWand ();
7774 ? MagickReadImage (image_wand
, filename
)
7775 : MagickReadImageBlob (image_wand
, contents
, size
))
7778 imagemagick_error (image_wand
);
7779 goto imagemagick_error
;
7782 /* Retrieve the frame's background color, for use later. */
7785 Lisp_Object specified_bg
;
7787 specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
7788 if (!STRINGP (specified_bg
)
7789 || !x_defined_color (f
, SSDATA (specified_bg
), &bgcolor
, 0))
7792 bgcolor
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
7793 x_query_color (f
, &bgcolor
);
7795 ns_query_color (FRAME_BACKGROUND_COLOR (f
), &bgcolor
, 1);
7799 bg_wand
= NewPixelWand ();
7800 PixelSetRed (bg_wand
, (double) bgcolor
.red
/ 65535);
7801 PixelSetGreen (bg_wand
, (double) bgcolor
.green
/ 65535);
7802 PixelSetBlue (bg_wand
, (double) bgcolor
.blue
/ 65535);
7805 compute_image_size (MagickGetImageWidth (image_wand
),
7806 MagickGetImageHeight (image_wand
),
7807 img
->spec
, &desired_width
, &desired_height
);
7809 if (desired_width
!= -1 && desired_height
!= -1)
7811 status
= MagickScaleImage (image_wand
, desired_width
, desired_height
);
7812 if (status
== MagickFalse
)
7814 image_error ("Imagemagick scale failed", Qnil
, Qnil
);
7815 imagemagick_error (image_wand
);
7816 goto imagemagick_error
;
7820 /* crop behaves similar to image slicing in Emacs but is more memory
7822 crop
= image_spec_value (img
->spec
, QCcrop
, NULL
);
7824 if (CONSP (crop
) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop
)))
7826 /* After some testing, it seems MagickCropImage is the fastest crop
7827 function in ImageMagick. This crop function seems to do less copying
7828 than the alternatives, but it still reads the entire image into memory
7829 before cropping, which is apparently difficult to avoid when using
7831 size_t crop_width
= XINT (XCAR (crop
));
7833 if (CONSP (crop
) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop
)))
7835 size_t crop_height
= XINT (XCAR (crop
));
7837 if (CONSP (crop
) && TYPE_RANGED_INTEGERP (ssize_t
, XCAR (crop
)))
7839 ssize_t crop_x
= XINT (XCAR (crop
));
7841 if (CONSP (crop
) && TYPE_RANGED_INTEGERP (ssize_t
, XCAR (crop
)))
7843 ssize_t crop_y
= XINT (XCAR (crop
));
7844 MagickCropImage (image_wand
, crop_width
, crop_height
,
7851 /* Furthermore :rotation. we need background color and angle for
7854 TODO background handling for rotation specified_bg =
7855 image_spec_value (img->spec, QCbackground, NULL); if (!STRINGP
7857 value
= image_spec_value (img
->spec
, QCrotation
, NULL
);
7860 rotation
= extract_float (value
);
7861 status
= MagickRotateImage (image_wand
, bg_wand
, rotation
);
7862 if (status
== MagickFalse
)
7864 image_error ("Imagemagick image rotate failed", Qnil
, Qnil
);
7865 imagemagick_error (image_wand
);
7866 goto imagemagick_error
;
7870 /* Set the canvas background color to the frame or specified
7871 background, and flatten the image. Note: as of ImageMagick
7872 6.6.0, SVG image transparency is not handled properly
7873 (e.g. etc/images/splash.svg shows a white background always). */
7875 MagickWand
*new_wand
;
7876 MagickSetImageBackgroundColor (image_wand
, bg_wand
);
7877 #ifdef HAVE_MAGICKMERGEIMAGELAYERS
7878 new_wand
= MagickMergeImageLayers (image_wand
, MergeLayer
);
7880 new_wand
= MagickFlattenImages (image_wand
);
7882 DestroyMagickWand (image_wand
);
7883 image_wand
= new_wand
;
7886 /* Finally we are done manipulating the image. Figure out the
7887 resulting width/height and transfer ownership to Emacs. */
7888 height
= MagickGetImageHeight (image_wand
);
7889 width
= MagickGetImageWidth (image_wand
);
7891 if (! (width
<= INT_MAX
&& height
<= INT_MAX
7892 && check_image_size (f
, width
, height
)))
7894 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7895 goto imagemagick_error
;
7898 /* We can now get a valid pixel buffer from the imagemagick file, if all
7901 init_color_table ();
7903 #ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
7904 if (imagemagick_render_type
!= 0)
7906 /* Magicexportimage is normally faster than pixelpushing. This
7907 method is also well tested. Some aspects of this method are
7908 ad-hoc and needs to be more researched. */
7909 int imagedepth
= 24; /*MagickGetImageDepth(image_wand);*/
7910 const char *exportdepth
= imagedepth
<= 8 ? "I" : "BGRP"; /*"RGBP";*/
7911 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7912 if (!x_create_x_image_and_pixmap (f
, width
, height
, imagedepth
,
7913 &ximg
, &img
->pixmap
))
7915 #ifdef COLOR_TABLE_SUPPORT
7916 free_color_table ();
7918 image_error ("Imagemagick X bitmap allocation failure", Qnil
, Qnil
);
7919 goto imagemagick_error
;
7922 /* Oddly, the below code doesn't seem to work:*/
7923 /* switch(ximg->bitmap_unit){ */
7925 /* pixelwidth=CharPixel; */
7928 /* pixelwidth=ShortPixel; */
7931 /* pixelwidth=LongPixel; */
7935 Here im just guessing the format of the bitmap.
7936 happens to work fine for:
7939 seems about 3 times as fast as pixel pushing(not carefully measured)
7941 pixelwidth
= CharPixel
; /*??? TODO figure out*/
7942 MagickExportImagePixels (image_wand
, 0, 0, width
, height
,
7943 exportdepth
, pixelwidth
, ximg
->data
);
7946 #endif /* HAVE_MAGICKEXPORTIMAGEPIXELS */
7948 size_t image_height
;
7950 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7951 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0,
7952 &ximg
, &img
->pixmap
))
7954 #ifdef COLOR_TABLE_SUPPORT
7955 free_color_table ();
7957 image_error ("Imagemagick X bitmap allocation failure", Qnil
, Qnil
);
7958 goto imagemagick_error
;
7961 /* Copy imagemagick image to x with primitive yet robust pixel
7962 pusher loop. This has been tested a lot with many different
7965 /* Copy pixels from the imagemagick image structure to the x image map. */
7966 iterator
= NewPixelIterator (image_wand
);
7967 if (iterator
== (PixelIterator
*) NULL
)
7969 #ifdef COLOR_TABLE_SUPPORT
7970 free_color_table ();
7972 x_destroy_x_image (ximg
);
7973 image_error ("Imagemagick pixel iterator creation failed",
7975 goto imagemagick_error
;
7978 image_height
= MagickGetImageHeight (image_wand
);
7979 for (y
= 0; y
< image_height
; y
++)
7981 pixels
= PixelGetNextIteratorRow (iterator
, &width
);
7982 if (pixels
== (PixelWand
**) NULL
)
7984 for (x
= 0; x
< (long) width
; x
++)
7986 PixelGetMagickColor (pixels
[x
], &pixel
);
7987 XPutPixel (ximg
, x
, y
,
7988 lookup_rgb_color (f
,
7994 DestroyPixelIterator (iterator
);
7997 #ifdef COLOR_TABLE_SUPPORT
7998 /* Remember colors allocated for this image. */
7999 img
->colors
= colors_in_color_table (&img
->ncolors
);
8000 free_color_table ();
8001 #endif /* COLOR_TABLE_SUPPORT */
8004 img
->height
= height
;
8006 /* Put the image into the pixmap, then free the X image and its
8008 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8009 x_destroy_x_image (ximg
);
8011 /* Final cleanup. image_wand should be the only resource left. */
8012 DestroyMagickWand (image_wand
);
8013 if (bg_wand
) DestroyPixelWand (bg_wand
);
8015 /* `MagickWandTerminus' terminates the imagemagick environment. */
8016 MagickWandTerminus ();
8021 DestroyMagickWand (image_wand
);
8022 if (bg_wand
) DestroyPixelWand (bg_wand
);
8024 MagickWandTerminus ();
8025 /* TODO more cleanup. */
8026 image_error ("Error parsing IMAGEMAGICK image `%s'", img
->spec
, Qnil
);
8031 /* Load IMAGEMAGICK image IMG for use on frame F. Value is true if
8032 successful. this function will go into the imagemagick_type structure, and
8033 the prototype thus needs to be compatible with that structure. */
8036 imagemagick_load (struct frame
*f
, struct image
*img
)
8039 Lisp_Object file_name
;
8041 /* If IMG->spec specifies a file name, create a non-file spec from it. */
8042 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
8043 if (STRINGP (file_name
))
8047 file
= x_find_image_file (file_name
);
8048 if (!STRINGP (file
))
8050 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
8053 success_p
= imagemagick_load_image (f
, img
, 0, 0, SSDATA (file
));
8055 /* Else its not a file, its a lisp object. Load the image from a
8056 lisp object rather than a file. */
8061 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8062 if (!STRINGP (data
))
8064 image_error ("Invalid image data `%s'", data
, Qnil
);
8067 success_p
= imagemagick_load_image (f
, img
, SDATA (data
),
8068 SBYTES (data
), NULL
);
8074 DEFUN ("imagemagick-types", Fimagemagick_types
, Simagemagick_types
, 0, 0, 0,
8075 doc
: /* Return a list of image types supported by ImageMagick.
8076 Each entry in this list is a symbol named after an ImageMagick format
8077 tag. See the ImageMagick manual for a list of ImageMagick formats and
8078 their descriptions (http://www.imagemagick.org/script/formats.php).
8079 You can also try the shell command: `identify -list format'.
8081 Note that ImageMagick recognizes many file-types that Emacs does not
8082 recognize as images, such as C. See `imagemagick-types-enable'
8083 and `imagemagick-types-inhibit'. */)
8086 Lisp_Object typelist
= Qnil
;
8091 Lisp_Object Qimagemagicktype
;
8093 GetExceptionInfo(&ex
);
8094 imtypes
= GetMagickList ("*", &numf
, &ex
);
8095 DestroyExceptionInfo(&ex
);
8097 for (i
= 0; i
< numf
; i
++)
8099 Qimagemagicktype
= intern (imtypes
[i
]);
8100 typelist
= Fcons (Qimagemagicktype
, typelist
);
8102 return Fnreverse (typelist
);
8105 #endif /* defined (HAVE_IMAGEMAGICK) */
8109 /***********************************************************************
8111 ***********************************************************************/
8113 #if defined (HAVE_RSVG)
8115 /* Function prototypes. */
8117 static bool svg_image_p (Lisp_Object object
);
8118 static bool svg_load (struct frame
*f
, struct image
*img
);
8120 static bool svg_load_image (struct frame
*, struct image
*,
8121 unsigned char *, ptrdiff_t);
8123 /* The symbol `svg' identifying images of this type. */
8125 static Lisp_Object Qsvg
;
8127 /* Indices of image specification fields in svg_format, below. */
8129 enum svg_keyword_index
8144 /* Vector of image_keyword structures describing the format
8145 of valid user-defined image specifications. */
8147 static const struct image_keyword svg_format
[SVG_LAST
] =
8149 {":type", IMAGE_SYMBOL_VALUE
, 1},
8150 {":data", IMAGE_STRING_VALUE
, 0},
8151 {":file", IMAGE_STRING_VALUE
, 0},
8152 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8153 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
8154 {":relief", IMAGE_INTEGER_VALUE
, 0},
8155 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8156 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8157 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8158 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8161 #if defined HAVE_NTGUI && defined WINDOWSNT
8162 static bool init_svg_functions (void);
8164 #define init_svg_functions NULL
8167 /* Structure describing the image type `svg'. Its the same type of
8168 structure defined for all image formats, handled by emacs image
8169 functions. See struct image_type in dispextern.h. */
8171 static struct image_type svg_type
=
8182 /* Return true if OBJECT is a valid SVG image specification. Do
8183 this by calling parse_image_spec and supplying the keywords that
8184 identify the SVG format. */
8187 svg_image_p (Lisp_Object object
)
8189 struct image_keyword fmt
[SVG_LAST
];
8190 memcpy (fmt
, svg_format
, sizeof fmt
);
8192 if (!parse_image_spec (object
, fmt
, SVG_LAST
, Qsvg
))
8195 /* Must specify either the :data or :file keyword. */
8196 return fmt
[SVG_FILE
].count
+ fmt
[SVG_DATA
].count
== 1;
8199 #include <librsvg/rsvg.h>
8203 /* SVG library functions. */
8204 DEF_IMGLIB_FN (RsvgHandle
*, rsvg_handle_new
, (void));
8205 DEF_IMGLIB_FN (void, rsvg_handle_get_dimensions
, (RsvgHandle
*, RsvgDimensionData
*));
8206 DEF_IMGLIB_FN (gboolean
, rsvg_handle_write
, (RsvgHandle
*, const guchar
*, gsize
, GError
**));
8207 DEF_IMGLIB_FN (gboolean
, rsvg_handle_close
, (RsvgHandle
*, GError
**));
8208 DEF_IMGLIB_FN (GdkPixbuf
*, rsvg_handle_get_pixbuf
, (RsvgHandle
*));
8209 DEF_IMGLIB_FN (void *, rsvg_handle_set_size_callback
, (RsvgHandle
*, RsvgSizeFunc
, gpointer
, GDestroyNotify
));
8211 DEF_IMGLIB_FN (int, gdk_pixbuf_get_width
, (const GdkPixbuf
*));
8212 DEF_IMGLIB_FN (int, gdk_pixbuf_get_height
, (const GdkPixbuf
*));
8213 DEF_IMGLIB_FN (guchar
*, gdk_pixbuf_get_pixels
, (const GdkPixbuf
*));
8214 DEF_IMGLIB_FN (int, gdk_pixbuf_get_rowstride
, (const GdkPixbuf
*));
8215 DEF_IMGLIB_FN (GdkColorspace
, gdk_pixbuf_get_colorspace
, (const GdkPixbuf
*));
8216 DEF_IMGLIB_FN (int, gdk_pixbuf_get_n_channels
, (const GdkPixbuf
*));
8217 DEF_IMGLIB_FN (gboolean
, gdk_pixbuf_get_has_alpha
, (const GdkPixbuf
*));
8218 DEF_IMGLIB_FN (int, gdk_pixbuf_get_bits_per_sample
, (const GdkPixbuf
*));
8220 DEF_IMGLIB_FN (void, g_type_init
, (void));
8221 DEF_IMGLIB_FN (void, g_object_unref
, (gpointer
));
8222 DEF_IMGLIB_FN (void, g_error_free
, (GError
*));
8224 Lisp_Object Qgdk_pixbuf
, Qglib
, Qgobject
;
8227 init_svg_functions (void)
8229 HMODULE library
, gdklib
, glib
, gobject
;
8231 if (!(glib
= w32_delayed_load (Qglib
))
8232 || !(gobject
= w32_delayed_load (Qgobject
))
8233 || !(gdklib
= w32_delayed_load (Qgdk_pixbuf
))
8234 || !(library
= w32_delayed_load (Qsvg
)))
8237 LOAD_IMGLIB_FN (library
, rsvg_handle_new
);
8238 LOAD_IMGLIB_FN (library
, rsvg_handle_get_dimensions
);
8239 LOAD_IMGLIB_FN (library
, rsvg_handle_write
);
8240 LOAD_IMGLIB_FN (library
, rsvg_handle_close
);
8241 LOAD_IMGLIB_FN (library
, rsvg_handle_get_pixbuf
);
8243 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_width
);
8244 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_height
);
8245 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_pixels
);
8246 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_rowstride
);
8247 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_colorspace
);
8248 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_n_channels
);
8249 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_has_alpha
);
8250 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_bits_per_sample
);
8252 LOAD_IMGLIB_FN (gobject
, g_type_init
);
8253 LOAD_IMGLIB_FN (gobject
, g_object_unref
);
8254 LOAD_IMGLIB_FN (glib
, g_error_free
);
8260 /* The following aliases for library functions allow dynamic loading
8261 to be used on some platforms. */
8262 #define fn_rsvg_handle_new rsvg_handle_new
8263 #define fn_rsvg_handle_get_dimensions rsvg_handle_get_dimensions
8264 #define fn_rsvg_handle_write rsvg_handle_write
8265 #define fn_rsvg_handle_close rsvg_handle_close
8266 #define fn_rsvg_handle_get_pixbuf rsvg_handle_get_pixbuf
8268 #define fn_gdk_pixbuf_get_width gdk_pixbuf_get_width
8269 #define fn_gdk_pixbuf_get_height gdk_pixbuf_get_height
8270 #define fn_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels
8271 #define fn_gdk_pixbuf_get_rowstride gdk_pixbuf_get_rowstride
8272 #define fn_gdk_pixbuf_get_colorspace gdk_pixbuf_get_colorspace
8273 #define fn_gdk_pixbuf_get_n_channels gdk_pixbuf_get_n_channels
8274 #define fn_gdk_pixbuf_get_has_alpha gdk_pixbuf_get_has_alpha
8275 #define fn_gdk_pixbuf_get_bits_per_sample gdk_pixbuf_get_bits_per_sample
8277 #define fn_g_type_init g_type_init
8278 #define fn_g_object_unref g_object_unref
8279 #define fn_g_error_free g_error_free
8280 #endif /* !WINDOWSNT */
8282 /* Load SVG image IMG for use on frame F. Value is true if
8286 svg_load (struct frame
*f
, struct image
*img
)
8289 Lisp_Object file_name
;
8291 /* If IMG->spec specifies a file name, create a non-file spec from it. */
8292 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
8293 if (STRINGP (file_name
))
8296 unsigned char *contents
;
8299 file
= x_find_image_file (file_name
);
8300 if (!STRINGP (file
))
8302 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
8306 /* Read the entire file into memory. */
8307 contents
= slurp_file (SSDATA (file
), &size
);
8308 if (contents
== NULL
)
8310 image_error ("Error loading SVG image `%s'", img
->spec
, Qnil
);
8313 /* If the file was slurped into memory properly, parse it. */
8314 success_p
= svg_load_image (f
, img
, contents
, size
);
8317 /* Else its not a file, its a lisp object. Load the image from a
8318 lisp object rather than a file. */
8323 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8324 if (!STRINGP (data
))
8326 image_error ("Invalid image data `%s'", data
, Qnil
);
8329 success_p
= svg_load_image (f
, img
, SDATA (data
), SBYTES (data
));
8335 /* svg_load_image is a helper function for svg_load, which does the
8336 actual loading given contents and size, apart from frame and image
8337 structures, passed from svg_load.
8339 Uses librsvg to do most of the image processing.
8341 Returns true when successful. */
8343 svg_load_image (struct frame
*f
, /* Pointer to emacs frame structure. */
8344 struct image
*img
, /* Pointer to emacs image structure. */
8345 unsigned char *contents
, /* String containing the SVG XML data to be parsed. */
8346 ptrdiff_t size
) /* Size of data in bytes. */
8348 RsvgHandle
*rsvg_handle
;
8349 RsvgDimensionData dimension_data
;
8354 const guint8
*pixels
;
8357 Lisp_Object specified_bg
;
8362 /* g_type_init is a glib function that must be called prior to using
8363 gnome type library functions. */
8365 /* Make a handle to a new rsvg object. */
8366 rsvg_handle
= fn_rsvg_handle_new ();
8368 /* Parse the contents argument and fill in the rsvg_handle. */
8369 fn_rsvg_handle_write (rsvg_handle
, contents
, size
, &err
);
8370 if (err
) goto rsvg_error
;
8372 /* The parsing is complete, rsvg_handle is ready to used, close it
8373 for further writes. */
8374 fn_rsvg_handle_close (rsvg_handle
, &err
);
8375 if (err
) goto rsvg_error
;
8377 fn_rsvg_handle_get_dimensions (rsvg_handle
, &dimension_data
);
8378 if (! check_image_size (f
, dimension_data
.width
, dimension_data
.height
))
8380 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
8384 /* We can now get a valid pixel buffer from the svg file, if all
8386 pixbuf
= fn_rsvg_handle_get_pixbuf (rsvg_handle
);
8387 if (!pixbuf
) goto rsvg_error
;
8388 fn_g_object_unref (rsvg_handle
);
8390 /* Extract some meta data from the svg handle. */
8391 width
= fn_gdk_pixbuf_get_width (pixbuf
);
8392 height
= fn_gdk_pixbuf_get_height (pixbuf
);
8393 pixels
= fn_gdk_pixbuf_get_pixels (pixbuf
);
8394 rowstride
= fn_gdk_pixbuf_get_rowstride (pixbuf
);
8396 /* Validate the svg meta data. */
8397 eassert (fn_gdk_pixbuf_get_colorspace (pixbuf
) == GDK_COLORSPACE_RGB
);
8398 eassert (fn_gdk_pixbuf_get_n_channels (pixbuf
) == 4);
8399 eassert (fn_gdk_pixbuf_get_has_alpha (pixbuf
));
8400 eassert (fn_gdk_pixbuf_get_bits_per_sample (pixbuf
) == 8);
8402 /* Try to create a x pixmap to hold the svg pixmap. */
8403 if (!x_create_x_image_and_pixmap (f
, width
, height
, 0, &ximg
, &img
->pixmap
))
8405 fn_g_object_unref (pixbuf
);
8409 init_color_table ();
8411 /* Handle alpha channel by combining the image with a background
8413 specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
8414 if (!STRINGP (specified_bg
)
8415 || !x_defined_color (f
, SSDATA (specified_bg
), &background
, 0))
8418 background
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
8419 x_query_color (f
, &background
);
8421 ns_query_color (FRAME_BACKGROUND_COLOR (f
), &background
, 1);
8425 /* SVG pixmaps specify transparency in the last byte, so right
8426 shift 8 bits to get rid of it, since emacs doesn't support
8428 background
.red
>>= 8;
8429 background
.green
>>= 8;
8430 background
.blue
>>= 8;
8432 /* This loop handles opacity values, since Emacs assumes
8433 non-transparent images. Each pixel must be "flattened" by
8434 calculating the resulting color, given the transparency of the
8435 pixel, and the image background color. */
8436 for (y
= 0; y
< height
; ++y
)
8438 for (x
= 0; x
< width
; ++x
)
8448 opacity
= *pixels
++;
8450 red
= ((red
* opacity
)
8451 + (background
.red
* ((1 << 8) - opacity
)));
8452 green
= ((green
* opacity
)
8453 + (background
.green
* ((1 << 8) - opacity
)));
8454 blue
= ((blue
* opacity
)
8455 + (background
.blue
* ((1 << 8) - opacity
)));
8457 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, red
, green
, blue
));
8460 pixels
+= rowstride
- 4 * width
;
8463 #ifdef COLOR_TABLE_SUPPORT
8464 /* Remember colors allocated for this image. */
8465 img
->colors
= colors_in_color_table (&img
->ncolors
);
8466 free_color_table ();
8467 #endif /* COLOR_TABLE_SUPPORT */
8469 fn_g_object_unref (pixbuf
);
8472 img
->height
= height
;
8474 /* Maybe fill in the background field while we have ximg handy.
8475 Casting avoids a GCC warning. */
8476 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
8478 /* Put the image into the pixmap, then free the X image and its
8480 x_put_x_image (f
, ximg
, img
->pixmap
, width
, height
);
8481 x_destroy_x_image (ximg
);
8486 fn_g_object_unref (rsvg_handle
);
8487 /* FIXME: Use error->message so the user knows what is the actual
8488 problem with the image. */
8489 image_error ("Error parsing SVG image `%s'", img
->spec
, Qnil
);
8490 fn_g_error_free (err
);
8494 #endif /* defined (HAVE_RSVG) */
8499 /***********************************************************************
8501 ***********************************************************************/
8503 #ifdef HAVE_X_WINDOWS
8504 #define HAVE_GHOSTSCRIPT 1
8505 #endif /* HAVE_X_WINDOWS */
8507 #ifdef HAVE_GHOSTSCRIPT
8509 static bool gs_image_p (Lisp_Object object
);
8510 static bool gs_load (struct frame
*f
, struct image
*img
);
8511 static void gs_clear_image (struct frame
*f
, struct image
*img
);
8513 /* Keyword symbols. */
8515 static Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
8517 /* Indices of image specification fields in gs_format, below. */
8519 enum gs_keyword_index
8537 /* Vector of image_keyword structures describing the format
8538 of valid user-defined image specifications. */
8540 static const struct image_keyword gs_format
[GS_LAST
] =
8542 {":type", IMAGE_SYMBOL_VALUE
, 1},
8543 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8544 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8545 {":file", IMAGE_STRING_VALUE
, 1},
8546 {":loader", IMAGE_FUNCTION_VALUE
, 0},
8547 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
8548 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8549 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
8550 {":relief", IMAGE_INTEGER_VALUE
, 0},
8551 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8552 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8553 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8554 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8557 /* Structure describing the image type `ghostscript'. */
8559 static struct image_type gs_type
=
8570 /* Free X resources of Ghostscript image IMG which is used on frame F. */
8573 gs_clear_image (struct frame
*f
, struct image
*img
)
8575 x_clear_image (f
, img
);
8579 /* Return true if OBJECT is a valid Ghostscript image
8583 gs_image_p (Lisp_Object object
)
8585 struct image_keyword fmt
[GS_LAST
];
8589 memcpy (fmt
, gs_format
, sizeof fmt
);
8591 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
8594 /* Bounding box must be a list or vector containing 4 integers. */
8595 tem
= fmt
[GS_BOUNDING_BOX
].value
;
8598 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
8599 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
8604 else if (VECTORP (tem
))
8606 if (ASIZE (tem
) != 4)
8608 for (i
= 0; i
< 4; ++i
)
8609 if (!INTEGERP (AREF (tem
, i
)))
8619 /* Load Ghostscript image IMG for use on frame F. Value is true
8623 gs_load (struct frame
*f
, struct image
*img
)
8625 uprintmax_t printnum1
, printnum2
;
8626 char buffer
[sizeof " " + INT_STRLEN_BOUND (printmax_t
)];
8627 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
8629 double in_width
, in_height
;
8630 Lisp_Object pixel_colors
= Qnil
;
8632 /* Compute pixel size of pixmap needed from the given size in the
8633 image specification. Sizes in the specification are in pt. 1 pt
8634 = 1/72 in, xdpi and ydpi are stored in the frame's X display
8636 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
8637 in_width
= INTEGERP (pt_width
) ? XFASTINT (pt_width
) / 72.0 : 0;
8638 in_width
*= FRAME_RES_X (f
);
8639 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
8640 in_height
= INTEGERP (pt_height
) ? XFASTINT (pt_height
) / 72.0 : 0;
8641 in_height
*= FRAME_RES_Y (f
);
8643 if (! (in_width
<= INT_MAX
&& in_height
<= INT_MAX
8644 && check_image_size (f
, in_width
, in_height
)))
8646 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
8649 img
->width
= in_width
;
8650 img
->height
= in_height
;
8652 /* Create the pixmap. */
8653 eassert (img
->pixmap
== NO_PIXMAP
);
8655 if (x_check_image_size (0, img
->width
, img
->height
))
8657 /* Only W32 version did BLOCK_INPUT here. ++kfs */
8659 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8660 img
->width
, img
->height
,
8661 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
8667 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
8671 /* Call the loader to fill the pixmap. It returns a process object
8672 if successful. We do not record_unwind_protect here because
8673 other places in redisplay like calling window scroll functions
8674 don't either. Let the Lisp loader use `unwind-protect' instead. */
8675 printnum1
= FRAME_X_WINDOW (f
);
8676 printnum2
= img
->pixmap
;
8677 window_and_pixmap_id
8678 = make_formatted_string (buffer
, "%"pMu
" %"pMu
, printnum1
, printnum2
);
8680 printnum1
= FRAME_FOREGROUND_PIXEL (f
);
8681 printnum2
= FRAME_BACKGROUND_PIXEL (f
);
8683 = make_formatted_string (buffer
, "%"pMu
" %"pMu
, printnum1
, printnum2
);
8685 XSETFRAME (frame
, f
);
8686 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
8688 loader
= intern ("gs-load-image");
8690 img
->lisp_data
= call6 (loader
, frame
, img
->spec
,
8691 make_number (img
->width
),
8692 make_number (img
->height
),
8693 window_and_pixmap_id
,
8695 return PROCESSP (img
->lisp_data
);
8699 /* Kill the Ghostscript process that was started to fill PIXMAP on
8700 frame F. Called from XTread_socket when receiving an event
8701 telling Emacs that Ghostscript has finished drawing. */
8704 x_kill_gs_process (Pixmap pixmap
, struct frame
*f
)
8706 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
8711 /* Find the image containing PIXMAP. */
8712 for (i
= 0; i
< c
->used
; ++i
)
8713 if (c
->images
[i
]->pixmap
== pixmap
)
8716 /* Should someone in between have cleared the image cache, for
8717 instance, give up. */
8721 /* Kill the GS process. We should have found PIXMAP in the image
8722 cache and its image should contain a process object. */
8724 eassert (PROCESSP (img
->lisp_data
));
8725 Fkill_process (img
->lisp_data
, Qnil
);
8726 img
->lisp_data
= Qnil
;
8728 #if defined (HAVE_X_WINDOWS)
8730 /* On displays with a mutable colormap, figure out the colors
8731 allocated for the image by looking at the pixels of an XImage for
8733 class = FRAME_X_VISUAL (f
)->class;
8734 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
8740 /* Try to get an XImage for img->pixmep. */
8741 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
8742 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
8747 /* Initialize the color table. */
8748 init_color_table ();
8750 /* For each pixel of the image, look its color up in the
8751 color table. After having done so, the color table will
8752 contain an entry for each color used by the image. */
8753 for (y
= 0; y
< img
->height
; ++y
)
8754 for (x
= 0; x
< img
->width
; ++x
)
8756 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
8757 lookup_pixel_color (f
, pixel
);
8760 /* Record colors in the image. Free color table and XImage. */
8761 #ifdef COLOR_TABLE_SUPPORT
8762 img
->colors
= colors_in_color_table (&img
->ncolors
);
8763 free_color_table ();
8765 XDestroyImage (ximg
);
8767 #if 0 /* This doesn't seem to be the case. If we free the colors
8768 here, we get a BadAccess later in x_clear_image when
8769 freeing the colors. */
8770 /* We have allocated colors once, but Ghostscript has also
8771 allocated colors on behalf of us. So, to get the
8772 reference counts right, free them once. */
8774 x_free_colors (f
, img
->colors
, img
->ncolors
);
8778 image_error ("Cannot get X image of `%s'; colors will not be freed",
8783 #endif /* HAVE_X_WINDOWS */
8785 /* Now that we have the pixmap, compute mask and transform the
8786 image if requested. */
8788 postprocess_image (f
, img
);
8792 #endif /* HAVE_GHOSTSCRIPT */
8795 /***********************************************************************
8797 ***********************************************************************/
8801 DEFUN ("imagep", Fimagep
, Simagep
, 1, 1, 0,
8802 doc
: /* Value is non-nil if SPEC is a valid image specification. */)
8805 return valid_image_p (spec
) ? Qt
: Qnil
;
8809 DEFUN ("lookup-image", Flookup_image
, Slookup_image
, 1, 1, 0, "")
8814 if (valid_image_p (spec
))
8815 id
= lookup_image (SELECTED_FRAME (), spec
);
8818 return make_number (id
);
8821 #endif /* GLYPH_DEBUG */
8824 /***********************************************************************
8826 ***********************************************************************/
8828 DEFUN ("init-image-library", Finit_image_library
, Sinit_image_library
, 1, 1, 0,
8829 doc
: /* Initialize image library implementing image type TYPE.
8830 Return non-nil if TYPE is a supported image type.
8832 If image libraries are loaded dynamically (currently only the case on
8833 MS-Windows), load the library for TYPE if it is not yet loaded, using
8834 the library file(s) specified by `dynamic-library-alist'. */)
8837 return lookup_image_type (type
) ? Qt
: Qnil
;
8840 /* Look up image type TYPE, and return a pointer to its image_type
8841 structure. Return 0 if TYPE is not a known image type. */
8843 static struct image_type
*
8844 lookup_image_type (Lisp_Object type
)
8846 /* Types pbm and xbm are built-in and always available. */
8847 if (EQ (type
, Qpbm
))
8848 return define_image_type (&pbm_type
);
8850 if (EQ (type
, Qxbm
))
8851 return define_image_type (&xbm_type
);
8853 #if defined (HAVE_XPM) || defined (HAVE_NS)
8854 if (EQ (type
, Qxpm
))
8855 return define_image_type (&xpm_type
);
8858 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8859 if (EQ (type
, Qjpeg
))
8860 return define_image_type (&jpeg_type
);
8863 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8864 if (EQ (type
, Qtiff
))
8865 return define_image_type (&tiff_type
);
8868 #if defined (HAVE_GIF) || defined (HAVE_NS)
8869 if (EQ (type
, Qgif
))
8870 return define_image_type (&gif_type
);
8873 #if defined (HAVE_PNG) || defined (HAVE_NS)
8874 if (EQ (type
, Qpng
))
8875 return define_image_type (&png_type
);
8878 #if defined (HAVE_RSVG)
8879 if (EQ (type
, Qsvg
))
8880 return define_image_type (&svg_type
);
8883 #if defined (HAVE_IMAGEMAGICK)
8884 if (EQ (type
, Qimagemagick
))
8885 return define_image_type (&imagemagick_type
);
8888 #ifdef HAVE_GHOSTSCRIPT
8889 if (EQ (type
, Qpostscript
))
8890 return define_image_type (&gs_type
);
8896 /* Reset image_types before dumping.
8897 Called from Fdump_emacs. */
8900 reset_image_types (void)
8904 struct image_type
*next
= image_types
->next
;
8905 xfree (image_types
);
8911 syms_of_image (void)
8913 /* Initialize this only once; it will be reset before dumping. */
8916 /* Must be defined now because we're going to update it below, while
8917 defining the supported image types. */
8918 DEFVAR_LISP ("image-types", Vimage_types
,
8919 doc
: /* List of potentially supported image types.
8920 Each element of the list is a symbol for an image type, like 'jpeg or 'png.
8921 To check whether it is really supported, use `image-type-available-p'. */);
8922 Vimage_types
= Qnil
;
8924 DEFVAR_LISP ("max-image-size", Vmax_image_size
,
8925 doc
: /* Maximum size of images.
8926 Emacs will not load an image into memory if its pixel width or
8927 pixel height exceeds this limit.
8929 If the value is an integer, it directly specifies the maximum
8930 image height and width, measured in pixels. If it is a floating
8931 point number, it specifies the maximum image height and width
8932 as a ratio to the frame height and width. If the value is
8933 non-numeric, there is no explicit limit on the size of images. */);
8934 Vmax_image_size
= make_float (MAX_IMAGE_SIZE
);
8936 DEFSYM (Qcount
, "count");
8937 DEFSYM (Qextension_data
, "extension-data");
8938 DEFSYM (Qdelay
, "delay");
8940 DEFSYM (QCascent
, ":ascent");
8941 DEFSYM (QCmargin
, ":margin");
8942 DEFSYM (QCrelief
, ":relief");
8943 DEFSYM (QCconversion
, ":conversion");
8944 DEFSYM (QCcolor_symbols
, ":color-symbols");
8945 DEFSYM (QCheuristic_mask
, ":heuristic-mask");
8946 DEFSYM (QCindex
, ":index");
8947 DEFSYM (QCgeometry
, ":geometry");
8948 DEFSYM (QCcrop
, ":crop");
8949 DEFSYM (QCrotation
, ":rotation");
8950 DEFSYM (QCmatrix
, ":matrix");
8951 DEFSYM (QCcolor_adjustment
, ":color-adjustment");
8952 DEFSYM (QCmask
, ":mask");
8954 DEFSYM (Qlaplace
, "laplace");
8955 DEFSYM (Qemboss
, "emboss");
8956 DEFSYM (Qedge_detection
, "edge-detection");
8957 DEFSYM (Qheuristic
, "heuristic");
8959 DEFSYM (Qpostscript
, "postscript");
8960 DEFSYM (QCmax_width
, ":max-width");
8961 DEFSYM (QCmax_height
, ":max-height");
8962 #ifdef HAVE_GHOSTSCRIPT
8963 ADD_IMAGE_TYPE (Qpostscript
);
8964 DEFSYM (QCloader
, ":loader");
8965 DEFSYM (QCbounding_box
, ":bounding-box");
8966 DEFSYM (QCpt_width
, ":pt-width");
8967 DEFSYM (QCpt_height
, ":pt-height");
8968 #endif /* HAVE_GHOSTSCRIPT */
8971 DEFSYM (Qlibpng_version
, "libpng-version");
8972 Fset (Qlibpng_version
,
8974 make_number (PNG_LIBPNG_VER
)
8981 DEFSYM (Qpbm
, "pbm");
8982 ADD_IMAGE_TYPE (Qpbm
);
8984 DEFSYM (Qxbm
, "xbm");
8985 ADD_IMAGE_TYPE (Qxbm
);
8987 #if defined (HAVE_XPM) || defined (HAVE_NS)
8988 DEFSYM (Qxpm
, "xpm");
8989 ADD_IMAGE_TYPE (Qxpm
);
8992 #if defined (HAVE_JPEG) || defined (HAVE_NS)
8993 DEFSYM (Qjpeg
, "jpeg");
8994 ADD_IMAGE_TYPE (Qjpeg
);
8997 #if defined (HAVE_TIFF) || defined (HAVE_NS)
8998 DEFSYM (Qtiff
, "tiff");
8999 ADD_IMAGE_TYPE (Qtiff
);
9002 #if defined (HAVE_GIF) || defined (HAVE_NS)
9003 DEFSYM (Qgif
, "gif");
9004 ADD_IMAGE_TYPE (Qgif
);
9007 #if defined (HAVE_PNG) || defined (HAVE_NS)
9008 DEFSYM (Qpng
, "png");
9009 ADD_IMAGE_TYPE (Qpng
);
9012 #if defined (HAVE_IMAGEMAGICK)
9013 DEFSYM (Qimagemagick
, "imagemagick");
9014 ADD_IMAGE_TYPE (Qimagemagick
);
9017 #if defined (HAVE_RSVG)
9018 DEFSYM (Qsvg
, "svg");
9019 ADD_IMAGE_TYPE (Qsvg
);
9021 /* Other libraries used directly by svg code. */
9022 DEFSYM (Qgdk_pixbuf
, "gdk-pixbuf");
9023 DEFSYM (Qglib
, "glib");
9024 DEFSYM (Qgobject
, "gobject");
9025 #endif /* HAVE_NTGUI */
9026 #endif /* HAVE_RSVG */
9028 defsubr (&Sinit_image_library
);
9029 #ifdef HAVE_IMAGEMAGICK
9030 defsubr (&Simagemagick_types
);
9032 defsubr (&Sclear_image_cache
);
9033 defsubr (&Simage_flush
);
9034 defsubr (&Simage_size
);
9035 defsubr (&Simage_mask_p
);
9036 defsubr (&Simage_metadata
);
9040 defsubr (&Slookup_image
);
9043 DEFVAR_BOOL ("cross-disabled-images", cross_disabled_images
,
9044 doc
: /* Non-nil means always draw a cross over disabled images.
9045 Disabled images are those having a `:conversion disabled' property.
9046 A cross is always drawn on black & white displays. */);
9047 cross_disabled_images
= 0;
9049 DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path
,
9050 doc
: /* List of directories to search for window system bitmap files. */);
9051 Vx_bitmap_file_path
= decode_env_path ((char *) 0, PATH_BITMAPS
);
9053 DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay
,
9054 doc
: /* Maximum time after which images are removed from the cache.
9055 When an image has not been displayed this many seconds, Emacs
9056 automatically removes it from the image cache. If the cache contains
9057 a large number of images, the actual eviction time may be shorter.
9058 The value can also be nil, meaning the cache is never cleared.
9060 The function `clear-image-cache' disregards this variable. */);
9061 Vimage_cache_eviction_delay
= make_number (300);
9062 #ifdef HAVE_IMAGEMAGICK
9063 DEFVAR_INT ("imagemagick-render-type", imagemagick_render_type
,
9064 doc
: /* Integer indicating which ImageMagick rendering method to use.
9066 0 -- the default method (pixel pushing)
9067 1 -- a newer method ("MagickExportImagePixels") that may perform
9068 better (speed etc) in some cases, but has not been as thoroughly
9069 tested with Emacs as the default method. This method requires
9070 ImageMagick version 6.4.6 (approximately) or later.
9072 /* MagickExportImagePixels is in 6.4.6-9, but not 6.4.4-10. */
9073 imagemagick_render_type
= 0;