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>
38 #include "dispextern.h"
39 #include "blockinput.h"
42 #include "character.h"
44 #include "termhooks.h"
47 #ifdef HAVE_SYS_STAT_H
49 #endif /* HAVE_SYS_STAT_H */
51 #ifdef HAVE_SYS_TYPES_H
52 #include <sys/types.h>
53 #endif /* HAVE_SYS_TYPES_H */
55 #ifdef HAVE_WINDOW_SYSTEM
57 #endif /* HAVE_WINDOW_SYSTEM */
60 #define COLOR_TABLE_SUPPORT 1
62 typedef struct x_bitmap_record Bitmap_Record
;
63 #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
64 #define NO_PIXMAP None
66 #define PIX_MASK_RETAIN 0
67 #define PIX_MASK_DRAW 1
68 #endif /* HAVE_X_WINDOWS */
72 /* We need (or want) w32.h only when we're _not_ compiling for Cygwin. */
77 /* W32_TODO : Color tables on W32. */
78 #undef COLOR_TABLE_SUPPORT
80 typedef struct w32_bitmap_record Bitmap_Record
;
81 #define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y)
84 #define PIX_MASK_RETAIN 0
85 #define PIX_MASK_DRAW 1
87 #define x_defined_color w32_defined_color
88 #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
90 /* Versions of libpng and libgif that we were compiled with, or -1 if
91 no PNG/GIF support was compiled in. This is tested by w32-win.el
92 to correctly set up the alist used to search for the respective
94 Lisp_Object Qlibpng_version
, Qlibgif_version
;
95 #endif /* HAVE_NTGUI */
98 #undef COLOR_TABLE_SUPPORT
100 typedef struct ns_bitmap_record Bitmap_Record
;
102 #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
105 #define PIX_MASK_RETAIN 0
106 #define PIX_MASK_DRAW 1
108 #define x_defined_color(f, name, color_def, alloc) \
109 ns_defined_color (f, name, color_def, alloc, 0)
110 #define DefaultDepthOfScreen(screen) x_display_list->n_planes
114 /* The symbol `postscript' identifying images of this type. */
116 static Lisp_Object Qpostscript
;
118 static void x_disable_image (struct frame
*, struct image
*);
119 static void x_edge_detection (struct frame
*, struct image
*, Lisp_Object
,
122 static void init_color_table (void);
123 static unsigned long lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
);
124 #ifdef COLOR_TABLE_SUPPORT
125 static void free_color_table (void);
126 static unsigned long *colors_in_color_table (int *n
);
129 static Lisp_Object QCmax_width
, QCmax_height
;
131 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
132 id, which is just an int that this section returns. Bitmaps are
133 reference counted so they can be shared among frames.
135 Bitmap indices are guaranteed to be > 0, so a negative number can
136 be used to indicate no bitmap.
138 If you use x_create_bitmap_from_data, then you must keep track of
139 the bitmaps yourself. That is, creating a bitmap from the same
140 data more than once will not be caught. */
143 /* Use with images created by ns_image_for_XPM. */
145 XGetPixel (XImagePtr ximage
, int x
, int y
)
147 return ns_get_pixel (ximage
, x
, y
);
150 /* Use with images created by ns_image_for_XPM; alpha set to 1;
151 pixel is assumed to be in RGB form. */
153 XPutPixel (XImagePtr ximage
, int x
, int y
, unsigned long pixel
)
155 ns_put_pixel (ximage
, x
, y
, pixel
);
160 /* Functions to access the contents of a bitmap, given an id. */
163 x_bitmap_height (struct frame
*f
, ptrdiff_t id
)
165 return FRAME_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
169 x_bitmap_width (struct frame
*f
, ptrdiff_t id
)
171 return FRAME_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
174 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
176 x_bitmap_pixmap (struct frame
*f
, ptrdiff_t id
)
178 /* HAVE_NTGUI needs the explicit cast here. */
179 return (ptrdiff_t) FRAME_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
183 #ifdef HAVE_X_WINDOWS
185 x_bitmap_mask (struct frame
*f
, ptrdiff_t id
)
187 return FRAME_DISPLAY_INFO (f
)->bitmaps
[id
- 1].mask
;
191 /* Allocate a new bitmap record. Returns index of new record. */
194 x_allocate_bitmap_record (struct frame
*f
)
196 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
199 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
200 return ++dpyinfo
->bitmaps_last
;
202 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
203 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
207 xpalloc (dpyinfo
->bitmaps
, &dpyinfo
->bitmaps_size
,
208 10, -1, sizeof *dpyinfo
->bitmaps
);
209 return ++dpyinfo
->bitmaps_last
;
212 /* Add one reference to the reference count of the bitmap with id ID. */
215 x_reference_bitmap (struct frame
*f
, ptrdiff_t id
)
217 ++FRAME_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
220 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
223 x_create_bitmap_from_data (struct frame
*f
, char *bits
, unsigned int width
, unsigned int height
)
225 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
228 #ifdef HAVE_X_WINDOWS
230 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
231 bits
, width
, height
);
234 #endif /* HAVE_X_WINDOWS */
238 bitmap
= CreateBitmap (width
, height
,
239 FRAME_DISPLAY_INFO (XFRAME (frame
))->n_planes
,
240 FRAME_DISPLAY_INFO (XFRAME (frame
))->n_cbits
,
244 #endif /* HAVE_NTGUI */
247 void *bitmap
= ns_image_from_XBM (bits
, width
, height
);
252 id
= x_allocate_bitmap_record (f
);
255 dpyinfo
->bitmaps
[id
- 1].img
= bitmap
;
256 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
259 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
260 dpyinfo
->bitmaps
[id
- 1].height
= height
;
261 dpyinfo
->bitmaps
[id
- 1].width
= width
;
262 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
264 #ifdef HAVE_X_WINDOWS
265 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
266 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
267 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
268 #endif /* HAVE_X_WINDOWS */
271 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
272 dpyinfo
->bitmaps
[id
- 1].hinst
= NULL
;
273 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
274 #endif /* HAVE_NTGUI */
279 /* Create bitmap from file FILE for frame F. */
282 x_create_bitmap_from_file (struct frame
*f
, Lisp_Object file
)
284 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
287 return -1; /* W32_TODO : bitmap support */
288 #endif /* HAVE_NTGUI */
292 void *bitmap
= ns_image_from_file (file
);
298 id
= x_allocate_bitmap_record (f
);
299 dpyinfo
->bitmaps
[id
- 1].img
= bitmap
;
300 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
301 dpyinfo
->bitmaps
[id
- 1].file
= xlispstrdup (file
);
302 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
303 dpyinfo
->bitmaps
[id
- 1].height
= ns_image_width (bitmap
);
304 dpyinfo
->bitmaps
[id
- 1].width
= ns_image_height (bitmap
);
308 #ifdef HAVE_X_WINDOWS
309 unsigned int width
, height
;
311 int xhot
, yhot
, result
;
316 /* Look for an existing bitmap with the same name. */
317 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
319 if (dpyinfo
->bitmaps
[id
].refcount
320 && dpyinfo
->bitmaps
[id
].file
321 && !strcmp (dpyinfo
->bitmaps
[id
].file
, SSDATA (file
)))
323 ++dpyinfo
->bitmaps
[id
].refcount
;
328 /* Search bitmap-file-path for the file, if appropriate. */
329 if (openp (Vx_bitmap_file_path
, file
, Qnil
, &found
, make_number (R_OK
)) < 0)
332 filename
= SSDATA (found
);
334 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
335 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
336 if (result
!= BitmapSuccess
)
339 id
= x_allocate_bitmap_record (f
);
340 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
341 dpyinfo
->bitmaps
[id
- 1].have_mask
= 0;
342 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
343 dpyinfo
->bitmaps
[id
- 1].file
= xlispstrdup (file
);
344 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
345 dpyinfo
->bitmaps
[id
- 1].height
= height
;
346 dpyinfo
->bitmaps
[id
- 1].width
= width
;
349 #endif /* HAVE_X_WINDOWS */
355 free_bitmap_record (Display_Info
*dpyinfo
, Bitmap_Record
*bm
)
357 #ifdef HAVE_X_WINDOWS
358 XFreePixmap (dpyinfo
->display
, bm
->pixmap
);
360 XFreePixmap (dpyinfo
->display
, bm
->mask
);
361 #endif /* HAVE_X_WINDOWS */
364 DeleteObject (bm
->pixmap
);
365 #endif /* HAVE_NTGUI */
368 ns_release_object (bm
->img
);
378 /* Remove reference to bitmap with id number ID. */
381 x_destroy_bitmap (struct frame
*f
, ptrdiff_t id
)
383 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
387 Bitmap_Record
*bm
= &dpyinfo
->bitmaps
[id
- 1];
389 if (--bm
->refcount
== 0)
392 free_bitmap_record (dpyinfo
, bm
);
398 /* Free all the bitmaps for the display specified by DPYINFO. */
401 x_destroy_all_bitmaps (Display_Info
*dpyinfo
)
404 Bitmap_Record
*bm
= dpyinfo
->bitmaps
;
406 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++, bm
++)
407 if (bm
->refcount
> 0)
408 free_bitmap_record (dpyinfo
, bm
);
410 dpyinfo
->bitmaps_last
= 0;
413 static bool x_create_x_image_and_pixmap (struct frame
*, int, int, int,
414 XImagePtr
*, Pixmap
*);
415 static void x_destroy_x_image (XImagePtr ximg
);
418 static XImagePtr_or_DC
image_get_x_image_or_dc (struct frame
*, struct image
*,
420 static void image_unget_x_image_or_dc (struct image
*, bool, XImagePtr_or_DC
,
423 static XImagePtr
image_get_x_image (struct frame
*, struct image
*, bool);
424 static void image_unget_x_image (struct image
*, bool, XImagePtr
);
425 #define image_get_x_image_or_dc(f, img, mask_p, dummy) \
426 image_get_x_image (f, img, mask_p)
427 #define image_unget_x_image_or_dc(img, mask_p, ximg, dummy) \
428 image_unget_x_image (img, mask_p, ximg)
431 #ifdef HAVE_X_WINDOWS
433 static void image_sync_to_pixmaps (struct frame
*, struct image
*);
435 /* Useful functions defined in the section
436 `Image type independent image structures' below. */
438 static unsigned long four_corners_best (XImagePtr ximg
,
441 unsigned long height
);
444 /* Create a mask of a bitmap. Note is this not a perfect mask.
445 It's nicer with some borders in this context */
448 x_create_bitmap_mask (struct frame
*f
, ptrdiff_t id
)
451 XImagePtr ximg
, mask_img
;
452 unsigned long width
, height
;
455 unsigned long x
, y
, xp
, xm
, yp
, ym
;
458 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
463 pixmap
= x_bitmap_pixmap (f
, id
);
464 width
= x_bitmap_width (f
, id
);
465 height
= x_bitmap_height (f
, id
);
468 ximg
= XGetImage (FRAME_X_DISPLAY (f
), pixmap
, 0, 0, width
, height
,
477 result
= x_create_x_image_and_pixmap (f
, width
, height
, 1, &mask_img
, &mask
);
482 XDestroyImage (ximg
);
486 bg
= four_corners_best (ximg
, NULL
, width
, height
);
488 for (y
= 0; y
< ximg
->height
; ++y
)
490 for (x
= 0; x
< ximg
->width
; ++x
)
492 xp
= x
!= ximg
->width
- 1 ? x
+ 1 : 0;
493 xm
= x
!= 0 ? x
- 1 : ximg
->width
- 1;
494 yp
= y
!= ximg
->height
- 1 ? y
+ 1 : 0;
495 ym
= y
!= 0 ? y
- 1 : ximg
->height
- 1;
496 if (XGetPixel (ximg
, x
, y
) == bg
497 && XGetPixel (ximg
, x
, yp
) == bg
498 && XGetPixel (ximg
, x
, ym
) == bg
499 && XGetPixel (ximg
, xp
, y
) == bg
500 && XGetPixel (ximg
, xp
, yp
) == bg
501 && XGetPixel (ximg
, xp
, ym
) == bg
502 && XGetPixel (ximg
, xm
, y
) == bg
503 && XGetPixel (ximg
, xm
, yp
) == bg
504 && XGetPixel (ximg
, xm
, ym
) == bg
)
505 XPutPixel (mask_img
, x
, y
, 0);
507 XPutPixel (mask_img
, x
, y
, 1);
511 eassert (input_blocked_p ());
512 gc
= XCreateGC (FRAME_X_DISPLAY (f
), mask
, 0, NULL
);
513 XPutImage (FRAME_X_DISPLAY (f
), mask
, gc
, mask_img
, 0, 0, 0, 0,
515 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
517 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
518 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
520 XDestroyImage (ximg
);
521 x_destroy_x_image (mask_img
);
524 #endif /* HAVE_X_WINDOWS */
527 /***********************************************************************
529 ***********************************************************************/
531 /* List of supported image types. Use define_image_type to add new
532 types. Use lookup_image_type to find a type for a given symbol. */
534 static struct image_type
*image_types
;
536 /* The symbol `xbm' which is used as the type symbol for XBM images. */
538 static Lisp_Object Qxbm
;
542 Lisp_Object QCascent
, QCmargin
, QCrelief
;
543 Lisp_Object QCconversion
;
544 static Lisp_Object QCheuristic_mask
;
545 static Lisp_Object QCcolor_symbols
;
546 static Lisp_Object QCindex
, QCmatrix
, QCcolor_adjustment
, QCmask
, QCgeometry
;
547 static Lisp_Object QCcrop
, QCrotation
;
551 static Lisp_Object Qcount
, Qextension_data
, Qdelay
;
552 static Lisp_Object Qlaplace
, Qemboss
, Qedge_detection
, Qheuristic
;
554 /* Forward function prototypes. */
556 static struct image_type
*lookup_image_type (Lisp_Object
);
557 static void x_laplace (struct frame
*, struct image
*);
558 static void x_emboss (struct frame
*, struct image
*);
559 static void x_build_heuristic_mask (struct frame
*, struct image
*,
562 #define CACHE_IMAGE_TYPE(type, status) \
563 do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
565 #define CACHE_IMAGE_TYPE(type, status)
568 #define ADD_IMAGE_TYPE(type) \
569 do { Vimage_types = Fcons (type, Vimage_types); } while (0)
571 /* Define a new image type from TYPE. This adds a copy of TYPE to
572 image_types and caches the loading status of TYPE. */
574 static struct image_type
*
575 define_image_type (struct image_type
*type
)
577 struct image_type
*p
= NULL
;
578 Lisp_Object target_type
= *type
->type
;
583 for (p
= image_types
; p
; p
= p
->next
)
584 if (EQ (*p
->type
, target_type
))
589 #if defined HAVE_NTGUI && defined WINDOWSNT
590 /* If we failed to load the library before, don't try again. */
591 Lisp_Object tested
= Fassq (target_type
, Vlibrary_cache
);
592 if (CONSP (tested
) && NILP (XCDR (tested
)))
597 type_valid
= type
->init ();
598 CACHE_IMAGE_TYPE (target_type
, type_valid
? Qt
: Qnil
);
604 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
605 The initialized data segment is read-only. */
606 p
= xmalloc (sizeof *p
);
608 p
->next
= image_types
;
618 /* Value is true if OBJECT is a valid Lisp image specification. A
619 valid image specification is a list whose car is the symbol
620 `image', and whose rest is a property list. The property list must
621 contain a value for key `:type'. That value must be the name of a
622 supported image type. The rest of the property list depends on the
626 valid_image_p (Lisp_Object object
)
634 for (tem
= XCDR (object
); CONSP (tem
); tem
= XCDR (tem
))
635 if (EQ (XCAR (tem
), QCtype
))
638 if (CONSP (tem
) && SYMBOLP (XCAR (tem
)))
640 struct image_type
*type
;
641 type
= lookup_image_type (XCAR (tem
));
643 valid_p
= type
->valid_p (object
);
654 /* Log error message with format string FORMAT and argument ARG.
655 Signaling an error, e.g. when an image cannot be loaded, is not a
656 good idea because this would interrupt redisplay, and the error
657 message display would lead to another redisplay. This function
658 therefore simply displays a message. */
661 image_error (const char *format
, Lisp_Object arg1
, Lisp_Object arg2
)
663 add_to_log (format
, arg1
, arg2
);
668 /***********************************************************************
670 ***********************************************************************/
672 enum image_value_type
674 IMAGE_DONT_CHECK_VALUE_TYPE
,
676 IMAGE_STRING_OR_NIL_VALUE
,
678 IMAGE_POSITIVE_INTEGER_VALUE
,
679 IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
,
680 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
683 IMAGE_FUNCTION_VALUE
,
688 /* Structure used when parsing image specifications. */
692 /* Name of keyword. */
695 /* The type of value allowed. */
696 enum image_value_type type
;
698 /* True means key must be present. */
701 /* Used to recognize duplicate keywords in a property list. */
704 /* The value that was found. */
709 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
710 has the format (image KEYWORD VALUE ...). One of the keyword/
711 value pairs must be `:type TYPE'. KEYWORDS is a vector of
712 image_keywords structures of size NKEYWORDS describing other
713 allowed keyword/value pairs. Value is true if SPEC is valid. */
716 parse_image_spec (Lisp_Object spec
, struct image_keyword
*keywords
,
717 int nkeywords
, Lisp_Object type
)
726 while (CONSP (plist
))
728 Lisp_Object key
, value
;
730 /* First element of a pair must be a symbol. */
732 plist
= XCDR (plist
);
736 /* There must follow a value. */
739 value
= XCAR (plist
);
740 plist
= XCDR (plist
);
742 /* Find key in KEYWORDS. Error if not found. */
743 for (i
= 0; i
< nkeywords
; ++i
)
744 if (strcmp (keywords
[i
].name
, SSDATA (SYMBOL_NAME (key
))) == 0)
750 /* Record that we recognized the keyword. If a keywords
751 was found more than once, it's an error. */
752 keywords
[i
].value
= value
;
753 if (keywords
[i
].count
> 1)
757 /* Check type of value against allowed type. */
758 switch (keywords
[i
].type
)
760 case IMAGE_STRING_VALUE
:
761 if (!STRINGP (value
))
765 case IMAGE_STRING_OR_NIL_VALUE
:
766 if (!STRINGP (value
) && !NILP (value
))
770 case IMAGE_SYMBOL_VALUE
:
771 if (!SYMBOLP (value
))
775 case IMAGE_POSITIVE_INTEGER_VALUE
:
776 if (! RANGED_INTEGERP (1, value
, INT_MAX
))
780 case IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
:
781 if (RANGED_INTEGERP (0, value
, INT_MAX
))
784 && RANGED_INTEGERP (0, XCAR (value
), INT_MAX
)
785 && RANGED_INTEGERP (0, XCDR (value
), INT_MAX
))
789 case IMAGE_ASCENT_VALUE
:
790 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
792 else if (RANGED_INTEGERP (0, value
, 100))
796 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
797 /* Unlike the other integer-related cases, this one does not
798 verify that VALUE fits in 'int'. This is because callers
800 if (!INTEGERP (value
) || XINT (value
) < 0)
804 case IMAGE_DONT_CHECK_VALUE_TYPE
:
807 case IMAGE_FUNCTION_VALUE
:
808 value
= indirect_function (value
);
809 if (!NILP (Ffunctionp (value
)))
813 case IMAGE_NUMBER_VALUE
:
814 if (!INTEGERP (value
) && !FLOATP (value
))
818 case IMAGE_INTEGER_VALUE
:
819 if (! TYPE_RANGED_INTEGERP (int, value
))
823 case IMAGE_BOOL_VALUE
:
824 if (!NILP (value
) && !EQ (value
, Qt
))
833 if (EQ (key
, QCtype
) && !EQ (type
, value
))
837 /* Check that all mandatory fields are present. */
838 for (i
= 0; i
< nkeywords
; ++i
)
839 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
846 /* Return the value of KEY in image specification SPEC. Value is nil
847 if KEY is not present in SPEC. Set *FOUND depending on whether KEY
848 was found in SPEC. */
851 image_spec_value (Lisp_Object spec
, Lisp_Object key
, bool *found
)
855 eassert (valid_image_p (spec
));
857 for (tail
= XCDR (spec
);
858 CONSP (tail
) && CONSP (XCDR (tail
));
859 tail
= XCDR (XCDR (tail
)))
861 if (EQ (XCAR (tail
), key
))
865 return XCAR (XCDR (tail
));
875 DEFUN ("image-size", Fimage_size
, Simage_size
, 1, 3, 0,
876 doc
: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
877 PIXELS non-nil means return the size in pixels, otherwise return the
878 size in canonical character units.
879 FRAME is the frame on which the image will be displayed. FRAME nil
880 or omitted means use the selected frame. */)
881 (Lisp_Object spec
, Lisp_Object pixels
, Lisp_Object frame
)
886 if (valid_image_p (spec
))
888 struct frame
*f
= decode_window_system_frame (frame
);
889 ptrdiff_t id
= lookup_image (f
, spec
);
890 struct image
*img
= IMAGE_FROM_ID (f
, id
);
891 int width
= img
->width
+ 2 * img
->hmargin
;
892 int height
= img
->height
+ 2 * img
->vmargin
;
895 size
= Fcons (make_float ((double) width
/ FRAME_COLUMN_WIDTH (f
)),
896 make_float ((double) height
/ FRAME_LINE_HEIGHT (f
)));
898 size
= Fcons (make_number (width
), make_number (height
));
901 error ("Invalid image specification");
907 DEFUN ("image-mask-p", Fimage_mask_p
, Simage_mask_p
, 1, 2, 0,
908 doc
: /* Return t if image SPEC has a mask bitmap.
909 FRAME is the frame on which the image will be displayed. FRAME nil
910 or omitted means use the selected frame. */)
911 (Lisp_Object spec
, Lisp_Object frame
)
916 if (valid_image_p (spec
))
918 struct frame
*f
= decode_window_system_frame (frame
);
919 ptrdiff_t id
= lookup_image (f
, spec
);
920 struct image
*img
= IMAGE_FROM_ID (f
, id
);
925 error ("Invalid image specification");
930 DEFUN ("image-metadata", Fimage_metadata
, Simage_metadata
, 1, 2, 0,
931 doc
: /* Return metadata for image SPEC.
932 FRAME is the frame on which the image will be displayed. FRAME nil
933 or omitted means use the selected frame. */)
934 (Lisp_Object spec
, Lisp_Object frame
)
939 if (valid_image_p (spec
))
941 struct frame
*f
= decode_window_system_frame (frame
);
942 ptrdiff_t id
= lookup_image (f
, spec
);
943 struct image
*img
= IMAGE_FROM_ID (f
, id
);
944 ext
= img
->lisp_data
;
951 /***********************************************************************
952 Image type independent image structures
953 ***********************************************************************/
955 #define MAX_IMAGE_SIZE 10.0
956 /* Allocate and return a new image structure for image specification
957 SPEC. SPEC has a hash value of HASH. */
959 static struct image
*
960 make_image (Lisp_Object spec
, EMACS_UINT hash
)
962 struct image
*img
= xzalloc (sizeof *img
);
963 Lisp_Object file
= image_spec_value (spec
, QCfile
, NULL
);
965 eassert (valid_image_p (spec
));
966 img
->dependencies
= NILP (file
) ? Qnil
: list1 (file
);
967 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
968 eassert (img
->type
!= NULL
);
970 img
->lisp_data
= Qnil
;
971 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
973 img
->corners
[BOT_CORNER
] = -1; /* Full image */
978 /* Free image IMG which was used on frame F, including its resources. */
981 free_image (struct frame
*f
, struct image
*img
)
985 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
987 /* Remove IMG from the hash table of its cache. */
989 img
->prev
->next
= img
->next
;
991 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
994 img
->next
->prev
= img
->prev
;
996 c
->images
[img
->id
] = NULL
;
998 /* Free resources, then free IMG. */
999 img
->type
->free (f
, img
);
1004 /* Return true if the given widths and heights are valid for display. */
1007 check_image_size (struct frame
*f
, int width
, int height
)
1011 if (width
<= 0 || height
<= 0)
1014 if (INTEGERP (Vmax_image_size
))
1015 return (width
<= XINT (Vmax_image_size
)
1016 && height
<= XINT (Vmax_image_size
));
1017 else if (FLOATP (Vmax_image_size
))
1021 w
= FRAME_PIXEL_WIDTH (f
);
1022 h
= FRAME_PIXEL_HEIGHT (f
);
1025 w
= h
= 1024; /* Arbitrary size for unknown frame. */
1026 return (width
<= XFLOAT_DATA (Vmax_image_size
) * w
1027 && height
<= XFLOAT_DATA (Vmax_image_size
) * h
);
1033 /* Prepare image IMG for display on frame F. Must be called before
1034 drawing an image. */
1037 prepare_image_for_display (struct frame
*f
, struct image
*img
)
1039 /* We're about to display IMG, so set its timestamp to `now'. */
1040 img
->timestamp
= current_timespec ();
1042 /* If IMG doesn't have a pixmap yet, load it now, using the image
1043 type dependent loader function. */
1044 if (img
->pixmap
== NO_PIXMAP
&& !img
->load_failed_p
)
1045 img
->load_failed_p
= ! img
->type
->load (f
, img
);
1047 #ifdef HAVE_X_WINDOWS
1048 if (!img
->load_failed_p
)
1051 image_sync_to_pixmaps (f
, img
);
1058 /* Value is the number of pixels for the ascent of image IMG when
1059 drawn in face FACE. */
1062 image_ascent (struct image
*img
, struct face
*face
, struct glyph_slice
*slice
)
1067 if (slice
->height
== img
->height
)
1068 height
= img
->height
+ img
->vmargin
;
1069 else if (slice
->y
== 0)
1070 height
= slice
->height
+ img
->vmargin
;
1072 height
= slice
->height
;
1074 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
1079 /* W32 specific version. Why?. ++kfs */
1080 ascent
= height
/ 2 - (FONT_DESCENT (face
->font
)
1081 - FONT_BASE (face
->font
)) / 2;
1083 /* This expression is arranged so that if the image can't be
1084 exactly centered, it will be moved slightly up. This is
1085 because a typical font is `top-heavy' (due to the presence
1086 uppercase letters), so the image placement should err towards
1087 being top-heavy too. It also just generally looks better. */
1088 ascent
= (height
+ FONT_BASE (face
->font
)
1089 - FONT_DESCENT (face
->font
) + 1) / 2;
1090 #endif /* HAVE_NTGUI */
1093 ascent
= height
/ 2;
1096 ascent
= height
* (img
->ascent
/ 100.0);
1102 /* Image background colors. */
1104 /* Find the "best" corner color of a bitmap.
1105 On W32, XIMG is assumed to a device context with the bitmap selected. */
1107 static RGB_PIXEL_COLOR
1108 four_corners_best (XImagePtr_or_DC ximg
, int *corners
,
1109 unsigned long width
, unsigned long height
)
1111 RGB_PIXEL_COLOR corner_pixels
[4], best
IF_LINT (= 0);
1114 if (corners
&& corners
[BOT_CORNER
] >= 0)
1116 /* Get the colors at the corner_pixels of ximg. */
1117 corner_pixels
[0] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[TOP_CORNER
]);
1118 corner_pixels
[1] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[TOP_CORNER
]);
1119 corner_pixels
[2] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[BOT_CORNER
] - 1);
1120 corner_pixels
[3] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[BOT_CORNER
] - 1);
1124 /* Get the colors at the corner_pixels of ximg. */
1125 corner_pixels
[0] = GET_PIXEL (ximg
, 0, 0);
1126 corner_pixels
[1] = GET_PIXEL (ximg
, width
- 1, 0);
1127 corner_pixels
[2] = GET_PIXEL (ximg
, width
- 1, height
- 1);
1128 corner_pixels
[3] = GET_PIXEL (ximg
, 0, height
- 1);
1130 /* Choose the most frequently found color as background. */
1131 for (i
= best_count
= 0; i
< 4; ++i
)
1135 for (j
= n
= 0; j
< 4; ++j
)
1136 if (corner_pixels
[i
] == corner_pixels
[j
])
1140 best
= corner_pixels
[i
], best_count
= n
;
1146 /* Portability macros */
1150 #define Free_Pixmap(display, pixmap) \
1151 DeleteObject (pixmap)
1153 #elif defined (HAVE_NS)
1155 #define Free_Pixmap(display, pixmap) \
1156 ns_release_object (pixmap)
1160 #define Free_Pixmap(display, pixmap) \
1161 XFreePixmap (display, pixmap)
1163 #endif /* !HAVE_NTGUI && !HAVE_NS */
1166 /* Return the `background' field of IMG. If IMG doesn't have one yet,
1167 it is guessed heuristically. If non-zero, XIMG is an existing
1168 XImage object (or device context with the image selected on W32) to
1169 use for the heuristic. */
1172 image_background (struct image
*img
, struct frame
*f
, XImagePtr_or_DC ximg
)
1174 if (! img
->background_valid
)
1175 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1177 bool free_ximg
= !ximg
;
1180 #endif /* HAVE_NTGUI */
1183 ximg
= image_get_x_image_or_dc (f
, img
, 0, &prev
);
1185 img
->background
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
1188 image_unget_x_image_or_dc (img
, 0, ximg
, prev
);
1190 img
->background_valid
= 1;
1193 return img
->background
;
1196 /* Return the `background_transparent' field of IMG. If IMG doesn't
1197 have one yet, it is guessed heuristically. If non-zero, MASK is an
1198 existing XImage object to use for the heuristic. */
1201 image_background_transparent (struct image
*img
, struct frame
*f
, XImagePtr_or_DC mask
)
1203 if (! img
->background_transparent_valid
)
1204 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1208 bool free_mask
= !mask
;
1211 #endif /* HAVE_NTGUI */
1214 mask
= image_get_x_image_or_dc (f
, img
, 1, &prev
);
1216 img
->background_transparent
1217 = (four_corners_best (mask
, img
->corners
, img
->width
, img
->height
) == PIX_MASK_RETAIN
);
1220 image_unget_x_image_or_dc (img
, 1, mask
, prev
);
1223 img
->background_transparent
= 0;
1225 img
->background_transparent_valid
= 1;
1228 return img
->background_transparent
;
1232 /***********************************************************************
1233 Helper functions for X image types
1234 ***********************************************************************/
1236 /* Clear X resources of image IMG on frame F according to FLAGS.
1237 FLAGS is bitwise-or of the following masks:
1238 CLEAR_IMAGE_PIXMAP free the pixmap if any.
1239 CLEAR_IMAGE_MASK means clear the mask pixmap if any.
1240 CLEAR_IMAGE_COLORS means free colors allocated for the image, if
1243 #define CLEAR_IMAGE_PIXMAP (1 << 0)
1244 #define CLEAR_IMAGE_MASK (1 << 1)
1245 #define CLEAR_IMAGE_COLORS (1 << 2)
1248 x_clear_image_1 (struct frame
*f
, struct image
*img
, int flags
)
1250 if (flags
& CLEAR_IMAGE_PIXMAP
)
1254 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
1255 img
->pixmap
= NO_PIXMAP
;
1256 /* NOTE (HAVE_NS): background color is NOT an indexed color! */
1257 img
->background_valid
= 0;
1259 #ifdef HAVE_X_WINDOWS
1262 x_destroy_x_image (img
->ximg
);
1264 img
->background_valid
= 0;
1269 if (flags
& CLEAR_IMAGE_MASK
)
1273 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
1274 img
->mask
= NO_PIXMAP
;
1275 img
->background_transparent_valid
= 0;
1277 #ifdef HAVE_X_WINDOWS
1280 x_destroy_x_image (img
->mask_img
);
1281 img
->mask_img
= NULL
;
1282 img
->background_transparent_valid
= 0;
1287 if ((flags
& CLEAR_IMAGE_COLORS
) && img
->ncolors
)
1289 /* W32_TODO: color table support. */
1290 #ifdef HAVE_X_WINDOWS
1291 x_free_colors (f
, img
->colors
, img
->ncolors
);
1292 #endif /* HAVE_X_WINDOWS */
1293 xfree (img
->colors
);
1300 /* Free X resources of image IMG which is used on frame F. */
1303 x_clear_image (struct frame
*f
, struct image
*img
)
1306 x_clear_image_1 (f
, img
,
1307 CLEAR_IMAGE_PIXMAP
| CLEAR_IMAGE_MASK
| CLEAR_IMAGE_COLORS
);
1312 /* Allocate color COLOR_NAME for image IMG on frame F. If color
1313 cannot be allocated, use DFLT. Add a newly allocated color to
1314 IMG->colors, so that it can be freed again. Value is the pixel
1317 static unsigned long
1318 x_alloc_image_color (struct frame
*f
, struct image
*img
, Lisp_Object color_name
,
1322 unsigned long result
;
1324 eassert (STRINGP (color_name
));
1326 if (x_defined_color (f
, SSDATA (color_name
), &color
, 1)
1327 && img
->ncolors
< min (min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *img
->colors
,
1330 /* This isn't called frequently so we get away with simply
1331 reallocating the color vector to the needed size, here. */
1332 ptrdiff_t ncolors
= img
->ncolors
+ 1;
1333 img
->colors
= xrealloc (img
->colors
, ncolors
* sizeof *img
->colors
);
1334 img
->colors
[ncolors
- 1] = color
.pixel
;
1335 img
->ncolors
= ncolors
;
1336 result
= color
.pixel
;
1346 /***********************************************************************
1348 ***********************************************************************/
1350 static void cache_image (struct frame
*f
, struct image
*img
);
1352 /* Return a new, initialized image cache that is allocated from the
1353 heap. Call free_image_cache to free an image cache. */
1355 struct image_cache
*
1356 make_image_cache (void)
1358 struct image_cache
*c
= xmalloc (sizeof *c
);
1361 c
->used
= c
->refcount
= 0;
1362 c
->images
= xmalloc (c
->size
* sizeof *c
->images
);
1363 c
->buckets
= xzalloc (IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
);
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. */
1479 struct timespec old
, t
;
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_timespec ();
1495 old
= timespec_sub (t
, dtotimespec (delay
));
1497 for (i
= 0; i
< c
->used
; ++i
)
1499 struct image
*img
= c
->images
[i
];
1500 if (img
&& timespec_cmp (img
->timestamp
, old
) < 0)
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
: /* Flush 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
)
1636 x_clear_image_1 (f
, img
, CLEAR_IMAGE_MASK
);
1640 /* Should we apply an image transformation algorithm? */
1641 conversion
= image_spec_value (spec
, QCconversion
, NULL
);
1642 if (EQ (conversion
, Qdisabled
))
1643 x_disable_image (f
, img
);
1644 else if (EQ (conversion
, Qlaplace
))
1646 else if (EQ (conversion
, Qemboss
))
1648 else if (CONSP (conversion
)
1649 && EQ (XCAR (conversion
), Qedge_detection
))
1652 tem
= XCDR (conversion
);
1654 x_edge_detection (f
, img
,
1655 Fplist_get (tem
, QCmatrix
),
1656 Fplist_get (tem
, QCcolor_adjustment
));
1662 /* Return the id of image with Lisp specification SPEC on frame F.
1663 SPEC must be a valid Lisp image specification (see valid_image_p). */
1666 lookup_image (struct frame
*f
, Lisp_Object spec
)
1671 /* F must be a window-system frame, and SPEC must be a valid image
1673 eassert (FRAME_WINDOW_P (f
));
1674 eassert (valid_image_p (spec
));
1676 /* Look up SPEC in the hash table of the image cache. */
1677 hash
= sxhash (spec
, 0);
1678 img
= search_image_cache (f
, spec
, hash
);
1679 if (img
&& img
->load_failed_p
)
1681 free_image (f
, img
);
1685 /* If not found, create a new image and cache it. */
1689 img
= make_image (spec
, hash
);
1690 cache_image (f
, img
);
1691 img
->load_failed_p
= ! img
->type
->load (f
, img
);
1692 img
->frame_foreground
= FRAME_FOREGROUND_PIXEL (f
);
1693 img
->frame_background
= FRAME_BACKGROUND_PIXEL (f
);
1695 /* If we can't load the image, and we don't have a width and
1696 height, use some arbitrary width and height so that we can
1697 draw a rectangle for it. */
1698 if (img
->load_failed_p
)
1702 value
= image_spec_value (spec
, QCwidth
, NULL
);
1703 img
->width
= (INTEGERP (value
)
1704 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
1705 value
= image_spec_value (spec
, QCheight
, NULL
);
1706 img
->height
= (INTEGERP (value
)
1707 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
1711 /* Handle image type independent image attributes
1712 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
1713 `:background COLOR'. */
1714 Lisp_Object ascent
, margin
, relief
, bg
;
1717 ascent
= image_spec_value (spec
, QCascent
, NULL
);
1718 if (INTEGERP (ascent
))
1719 img
->ascent
= XFASTINT (ascent
);
1720 else if (EQ (ascent
, Qcenter
))
1721 img
->ascent
= CENTERED_IMAGE_ASCENT
;
1723 margin
= image_spec_value (spec
, QCmargin
, NULL
);
1724 if (INTEGERP (margin
))
1725 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
1726 else if (CONSP (margin
))
1728 img
->hmargin
= XFASTINT (XCAR (margin
));
1729 img
->vmargin
= XFASTINT (XCDR (margin
));
1732 relief
= image_spec_value (spec
, QCrelief
, NULL
);
1733 relief_bound
= INT_MAX
- max (img
->hmargin
, img
->vmargin
);
1734 if (RANGED_INTEGERP (- relief_bound
, relief
, relief_bound
))
1736 img
->relief
= XINT (relief
);
1737 img
->hmargin
+= eabs (img
->relief
);
1738 img
->vmargin
+= eabs (img
->relief
);
1741 if (! img
->background_valid
)
1743 bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
1747 = x_alloc_image_color (f
, img
, bg
,
1748 FRAME_BACKGROUND_PIXEL (f
));
1749 img
->background_valid
= 1;
1753 /* Do image transformations and compute masks, unless we
1754 don't have the image yet. */
1755 if (!EQ (*img
->type
->type
, Qpostscript
))
1756 postprocess_image (f
, img
);
1762 /* We're using IMG, so set its timestamp to `now'. */
1763 img
->timestamp
= current_timespec ();
1765 /* Value is the image id. */
1770 /* Cache image IMG in the image cache of frame F. */
1773 cache_image (struct frame
*f
, struct image
*img
)
1775 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1778 /* Find a free slot in c->images. */
1779 for (i
= 0; i
< c
->used
; ++i
)
1780 if (c
->images
[i
] == NULL
)
1783 /* If no free slot found, maybe enlarge c->images. */
1784 if (i
== c
->used
&& c
->used
== c
->size
)
1785 c
->images
= xpalloc (c
->images
, &c
->size
, 1, -1, sizeof *c
->images
);
1787 /* Add IMG to c->images, and assign IMG an id. */
1793 /* Add IMG to the cache's hash table. */
1794 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1795 img
->next
= c
->buckets
[i
];
1797 img
->next
->prev
= img
;
1799 c
->buckets
[i
] = img
;
1803 /* Call FN on every image in the image cache of frame F. Used to mark
1804 Lisp Objects in the image cache. */
1806 /* Mark Lisp objects in image IMG. */
1809 mark_image (struct image
*img
)
1811 mark_object (img
->spec
);
1812 mark_object (img
->dependencies
);
1814 if (!NILP (img
->lisp_data
))
1815 mark_object (img
->lisp_data
);
1820 mark_image_cache (struct image_cache
*c
)
1825 for (i
= 0; i
< c
->used
; ++i
)
1827 mark_image (c
->images
[i
]);
1833 /***********************************************************************
1834 X / NS / W32 support code
1835 ***********************************************************************/
1839 /* Macro for defining functions that will be loaded from image DLLs. */
1840 #define DEF_IMGLIB_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args
1842 /* Macro for loading those image functions from the library. */
1843 #define LOAD_IMGLIB_FN(lib,func) { \
1844 fn_##func = (void *) GetProcAddress (lib, #func); \
1845 if (!fn_##func) return 0; \
1848 #endif /* WINDOWSNT */
1850 /* Return true if XIMG's size WIDTH x HEIGHT doesn't break the
1852 WIDTH and HEIGHT must both be positive.
1853 If XIMG is null, assume it is a bitmap. */
1855 x_check_image_size (XImagePtr ximg
, int width
, int height
)
1857 #ifdef HAVE_X_WINDOWS
1858 /* Respect Xlib's limits: it cannot deal with images that have more
1859 than INT_MAX (and/or UINT_MAX) bytes. And respect Emacs's limits
1860 of PTRDIFF_MAX (and/or SIZE_MAX) bytes for any object. */
1863 XLIB_BYTES_MAX
= min (INT_MAX
, UINT_MAX
),
1864 X_IMAGE_BYTES_MAX
= min (XLIB_BYTES_MAX
, min (PTRDIFF_MAX
, SIZE_MAX
))
1867 int bitmap_pad
, depth
, bytes_per_line
;
1870 bitmap_pad
= ximg
->bitmap_pad
;
1871 depth
= ximg
->depth
;
1872 bytes_per_line
= ximg
->bytes_per_line
;
1878 bytes_per_line
= (width
>> 3) + ((width
& 7) != 0);
1880 return (width
<= (INT_MAX
- (bitmap_pad
- 1)) / depth
1881 && height
<= X_IMAGE_BYTES_MAX
/ bytes_per_line
);
1883 /* FIXME: Implement this check for the HAVE_NS and HAVE_NTGUI cases.
1884 For now, assume that every image size is allowed on these systems. */
1889 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
1890 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
1891 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
1892 via xmalloc. Print error messages via image_error if an error
1893 occurs. Value is true if successful.
1895 On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
1896 should indicate the bit depth of the image. */
1899 x_create_x_image_and_pixmap (struct frame
*f
, int width
, int height
, int depth
,
1900 XImagePtr
*ximg
, Pixmap
*pixmap
)
1902 #ifdef HAVE_X_WINDOWS
1903 Display
*display
= FRAME_X_DISPLAY (f
);
1904 Window window
= FRAME_X_WINDOW (f
);
1905 Screen
*screen
= FRAME_X_SCREEN (f
);
1907 eassert (input_blocked_p ());
1910 depth
= DefaultDepthOfScreen (screen
);
1911 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
1912 depth
, ZPixmap
, 0, NULL
, width
, height
,
1913 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
1916 image_error ("Unable to allocate X image", Qnil
, Qnil
);
1920 if (! x_check_image_size (*ximg
, width
, height
))
1922 x_destroy_x_image (*ximg
);
1924 image_error ("Image too large (%dx%d)",
1925 make_number (width
), make_number (height
));
1929 /* Allocate image raster. */
1930 (*ximg
)->data
= xmalloc ((*ximg
)->bytes_per_line
* height
);
1932 /* Allocate a pixmap of the same size. */
1933 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
1934 if (*pixmap
== NO_PIXMAP
)
1936 x_destroy_x_image (*ximg
);
1938 image_error ("Unable to create X pixmap", Qnil
, Qnil
);
1943 #endif /* HAVE_X_WINDOWS */
1947 BITMAPINFOHEADER
*header
;
1949 int scanline_width_bits
;
1951 int palette_colors
= 0;
1956 if (depth
!= 1 && depth
!= 4 && depth
!= 8
1957 && depth
!= 16 && depth
!= 24 && depth
!= 32)
1959 image_error ("Invalid image bit depth specified", Qnil
, Qnil
);
1963 scanline_width_bits
= width
* depth
;
1964 remainder
= scanline_width_bits
% 32;
1967 scanline_width_bits
+= 32 - remainder
;
1969 /* Bitmaps with a depth less than 16 need a palette. */
1970 /* BITMAPINFO structure already contains the first RGBQUAD. */
1972 palette_colors
= 1 << (depth
- 1);
1974 *ximg
= xmalloc (sizeof (XImage
) + palette_colors
* sizeof (RGBQUAD
));
1976 header
= &(*ximg
)->info
.bmiHeader
;
1977 memset (&(*ximg
)->info
, 0, sizeof (BITMAPINFO
));
1978 header
->biSize
= sizeof (*header
);
1979 header
->biWidth
= width
;
1980 header
->biHeight
= -height
; /* negative indicates a top-down bitmap. */
1981 header
->biPlanes
= 1;
1982 header
->biBitCount
= depth
;
1983 header
->biCompression
= BI_RGB
;
1984 header
->biClrUsed
= palette_colors
;
1986 /* TODO: fill in palette. */
1989 (*ximg
)->info
.bmiColors
[0].rgbBlue
= 0;
1990 (*ximg
)->info
.bmiColors
[0].rgbGreen
= 0;
1991 (*ximg
)->info
.bmiColors
[0].rgbRed
= 0;
1992 (*ximg
)->info
.bmiColors
[0].rgbReserved
= 0;
1993 (*ximg
)->info
.bmiColors
[1].rgbBlue
= 255;
1994 (*ximg
)->info
.bmiColors
[1].rgbGreen
= 255;
1995 (*ximg
)->info
.bmiColors
[1].rgbRed
= 255;
1996 (*ximg
)->info
.bmiColors
[1].rgbReserved
= 0;
1999 hdc
= get_frame_dc (f
);
2001 /* Create a DIBSection and raster array for the bitmap,
2002 and store its handle in *pixmap. */
2003 *pixmap
= CreateDIBSection (hdc
, &((*ximg
)->info
),
2004 (depth
< 16) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
,
2005 /* casting avoids a GCC warning */
2006 (void **)&((*ximg
)->data
), NULL
, 0);
2008 /* Realize display palette and garbage all frames. */
2009 release_frame_dc (f
, hdc
);
2011 if (*pixmap
== NULL
)
2013 DWORD err
= GetLastError ();
2014 Lisp_Object errcode
;
2015 /* All system errors are < 10000, so the following is safe. */
2016 XSETINT (errcode
, err
);
2017 image_error ("Unable to create bitmap, error code %d", errcode
, Qnil
);
2018 x_destroy_x_image (*ximg
);
2024 #endif /* HAVE_NTGUI */
2027 *pixmap
= ns_image_for_XPM (width
, height
, depth
);
2031 image_error ("Unable to allocate NSImage for XPM pixmap", Qnil
, Qnil
);
2040 /* Destroy XImage XIMG. Free XIMG->data. */
2043 x_destroy_x_image (XImagePtr ximg
)
2045 eassert (input_blocked_p ());
2048 #ifdef HAVE_X_WINDOWS
2051 XDestroyImage (ximg
);
2052 #endif /* HAVE_X_WINDOWS */
2054 /* Data will be freed by DestroyObject. */
2057 #endif /* HAVE_NTGUI */
2059 ns_release_object (ximg
);
2060 #endif /* HAVE_NS */
2065 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
2066 are width and height of both the image and pixmap. */
2069 x_put_x_image (struct frame
*f
, XImagePtr ximg
, Pixmap pixmap
, int width
, int height
)
2071 #ifdef HAVE_X_WINDOWS
2074 eassert (input_blocked_p ());
2075 gc
= XCreateGC (FRAME_X_DISPLAY (f
), pixmap
, 0, NULL
);
2076 XPutImage (FRAME_X_DISPLAY (f
), pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
2077 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
2078 #endif /* HAVE_X_WINDOWS */
2081 #if 0 /* I don't think this is necessary looking at where it is used. */
2082 HDC hdc
= get_frame_dc (f
);
2083 SetDIBits (hdc
, pixmap
, 0, height
, ximg
->data
, &(ximg
->info
), DIB_RGB_COLORS
);
2084 release_frame_dc (f
, hdc
);
2086 #endif /* HAVE_NTGUI */
2089 eassert (ximg
== pixmap
);
2090 ns_retain_object (ximg
);
2094 /* Thin wrapper for x_create_x_image_and_pixmap, so that it matches
2095 with image_put_x_image. */
2098 image_create_x_image_and_pixmap (struct frame
*f
, struct image
*img
,
2099 int width
, int height
, int depth
,
2100 XImagePtr
*ximg
, bool mask_p
)
2102 eassert ((!mask_p
? img
->pixmap
: img
->mask
) == NO_PIXMAP
);
2104 return x_create_x_image_and_pixmap (f
, width
, height
, depth
, ximg
,
2105 !mask_p
? &img
->pixmap
: &img
->mask
);
2108 /* Put X image XIMG into image IMG on frame F, as a mask if and only
2109 if MASK_P. On X, this simply records XIMG on a member of IMG, so
2110 it can be put into the pixmap afterwards via image_sync_to_pixmaps.
2111 On the other platforms, it puts XIMG into the pixmap, then frees
2112 the X image and its buffer. */
2115 image_put_x_image (struct frame
*f
, struct image
*img
, XImagePtr ximg
,
2118 #ifdef HAVE_X_WINDOWS
2121 eassert (img
->ximg
== NULL
);
2126 eassert (img
->mask_img
== NULL
);
2127 img
->mask_img
= ximg
;
2130 x_put_x_image (f
, ximg
, !mask_p
? img
->pixmap
: img
->mask
,
2131 img
->width
, img
->height
);
2132 x_destroy_x_image (ximg
);
2136 #ifdef HAVE_X_WINDOWS
2137 /* Put the X images recorded in IMG on frame F into pixmaps, then free
2138 the X images and their buffers. */
2141 image_sync_to_pixmaps (struct frame
*f
, struct image
*img
)
2145 x_put_x_image (f
, img
->ximg
, img
->pixmap
, img
->width
, img
->height
);
2146 x_destroy_x_image (img
->ximg
);
2151 x_put_x_image (f
, img
->mask_img
, img
->mask
, img
->width
, img
->height
);
2152 x_destroy_x_image (img
->mask_img
);
2153 img
->mask_img
= NULL
;
2159 /* Create a memory device context for IMG on frame F. It stores the
2160 currently selected GDI object into *PREV for future restoration by
2161 image_unget_x_image_or_dc. */
2163 static XImagePtr_or_DC
2164 image_get_x_image_or_dc (struct frame
*f
, struct image
*img
, bool mask_p
,
2167 HDC frame_dc
= get_frame_dc (f
);
2168 XImagePtr_or_DC ximg
= CreateCompatibleDC (frame_dc
);
2170 release_frame_dc (f
, frame_dc
);
2171 *prev
= SelectObject (ximg
, !mask_p
? img
->pixmap
: img
->mask
);
2177 image_unget_x_image_or_dc (struct image
*img
, bool mask_p
,
2178 XImagePtr_or_DC ximg
, HGDIOBJ prev
)
2180 SelectObject (ximg
, prev
);
2183 #else /* !HAVE_NTGUI */
2184 /* Get the X image for IMG on frame F. The resulting X image data
2185 should be treated as read-only at least on X. */
2188 image_get_x_image (struct frame
*f
, struct image
*img
, bool mask_p
)
2190 #ifdef HAVE_X_WINDOWS
2191 XImagePtr ximg_in_img
= !mask_p
? img
->ximg
: img
->mask_img
;
2196 return XGetImage (FRAME_X_DISPLAY (f
), !mask_p
? img
->pixmap
: img
->mask
,
2197 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
2198 #elif defined (HAVE_NS)
2199 XImagePtr pixmap
= !mask_p
? img
->pixmap
: img
->mask
;
2201 ns_retain_object (pixmap
);
2207 image_unget_x_image (struct image
*img
, bool mask_p
, XImagePtr ximg
)
2209 #ifdef HAVE_X_WINDOWS
2210 XImagePtr ximg_in_img
= !mask_p
? img
->ximg
: img
->mask_img
;
2213 eassert (ximg
== ximg_in_img
);
2215 XDestroyImage (ximg
);
2216 #elif defined (HAVE_NS)
2217 ns_release_object (ximg
);
2220 #endif /* !HAVE_NTGUI */
2223 /***********************************************************************
2225 ***********************************************************************/
2227 /* Find image file FILE. Look in data-directory/images, then
2228 x-bitmap-file-path. Value is the encoded full name of the file
2229 found, or nil if not found. */
2232 x_find_image_file (Lisp_Object file
)
2234 Lisp_Object file_found
, search_path
;
2237 /* TODO I think this should use something like image-load-path
2238 instead. Unfortunately, that can contain non-string elements. */
2239 search_path
= Fcons (Fexpand_file_name (build_string ("images"),
2241 Vx_bitmap_file_path
);
2243 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
2244 fd
= openp (search_path
, file
, Qnil
, &file_found
, Qnil
);
2250 file_found
= ENCODE_FILE (file_found
);
2259 /* Read FILE into memory. Value is a pointer to a buffer allocated
2260 with xmalloc holding FILE's contents. Value is null if an error
2261 occurred. *SIZE is set to the size of the file. */
2263 static unsigned char *
2264 slurp_file (char *file
, ptrdiff_t *size
)
2266 FILE *fp
= emacs_fopen (file
, "rb");
2267 unsigned char *buf
= NULL
;
2272 ptrdiff_t count
= SPECPDL_INDEX ();
2273 record_unwind_protect_ptr (fclose_unwind
, fp
);
2275 if (fstat (fileno (fp
), &st
) == 0
2276 && 0 <= st
.st_size
&& st
.st_size
< min (PTRDIFF_MAX
, SIZE_MAX
))
2278 /* Report an error if we read past the purported EOF.
2279 This can happen if the file grows as we read it. */
2280 ptrdiff_t buflen
= st
.st_size
;
2281 buf
= xmalloc (buflen
+ 1);
2282 if (fread (buf
, 1, buflen
+ 1, fp
) == buflen
)
2291 unbind_to (count
, Qnil
);
2299 /***********************************************************************
2301 ***********************************************************************/
2303 static bool xbm_load (struct frame
*f
, struct image
*img
);
2304 static bool xbm_image_p (Lisp_Object object
);
2305 static bool xbm_file_p (Lisp_Object
);
2308 /* Indices of image specification fields in xbm_format, below. */
2310 enum xbm_keyword_index
2328 /* Vector of image_keyword structures describing the format
2329 of valid XBM image specifications. */
2331 static const struct image_keyword xbm_format
[XBM_LAST
] =
2333 {":type", IMAGE_SYMBOL_VALUE
, 1},
2334 {":file", IMAGE_STRING_VALUE
, 0},
2335 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2336 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2337 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2338 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
2339 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
2340 {":ascent", IMAGE_ASCENT_VALUE
, 0},
2341 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
2342 {":relief", IMAGE_INTEGER_VALUE
, 0},
2343 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2344 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2345 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
2348 /* Structure describing the image type XBM. */
2350 static struct image_type xbm_type
=
2360 /* Tokens returned from xbm_scan. */
2369 /* Return true if OBJECT is a valid XBM-type image specification.
2370 A valid specification is a list starting with the symbol `image'
2371 The rest of the list is a property list which must contain an
2374 If the specification specifies a file to load, it must contain
2375 an entry `:file FILENAME' where FILENAME is a string.
2377 If the specification is for a bitmap loaded from memory it must
2378 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
2379 WIDTH and HEIGHT are integers > 0. DATA may be:
2381 1. a string large enough to hold the bitmap data, i.e. it must
2382 have a size >= (WIDTH + 7) / 8 * HEIGHT
2384 2. a bool-vector of size >= WIDTH * HEIGHT
2386 3. a vector of strings or bool-vectors, one for each line of the
2389 4. a string containing an in-memory XBM file. WIDTH and HEIGHT
2390 may not be specified in this case because they are defined in the
2393 Both the file and data forms may contain the additional entries
2394 `:background COLOR' and `:foreground COLOR'. If not present,
2395 foreground and background of the frame on which the image is
2396 displayed is used. */
2399 xbm_image_p (Lisp_Object object
)
2401 struct image_keyword kw
[XBM_LAST
];
2403 memcpy (kw
, xbm_format
, sizeof kw
);
2404 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
2407 eassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
2409 if (kw
[XBM_FILE
].count
)
2411 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
2414 else if (kw
[XBM_DATA
].count
&& xbm_file_p (kw
[XBM_DATA
].value
))
2416 /* In-memory XBM file. */
2417 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_FILE
].count
)
2425 /* Entries for `:width', `:height' and `:data' must be present. */
2426 if (!kw
[XBM_WIDTH
].count
2427 || !kw
[XBM_HEIGHT
].count
2428 || !kw
[XBM_DATA
].count
)
2431 data
= kw
[XBM_DATA
].value
;
2432 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
2433 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
2435 /* Check type of data, and width and height against contents of
2441 /* Number of elements of the vector must be >= height. */
2442 if (ASIZE (data
) < height
)
2445 /* Each string or bool-vector in data must be large enough
2446 for one line of the image. */
2447 for (i
= 0; i
< height
; ++i
)
2449 Lisp_Object elt
= AREF (data
, i
);
2454 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
2457 else if (BOOL_VECTOR_P (elt
))
2459 if (bool_vector_size (elt
) < width
)
2466 else if (STRINGP (data
))
2469 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
2472 else if (BOOL_VECTOR_P (data
))
2474 if (bool_vector_size (data
) / height
< width
)
2485 /* Scan a bitmap file. FP is the stream to read from. Value is
2486 either an enumerator from enum xbm_token, or a character for a
2487 single-character token, or 0 at end of file. If scanning an
2488 identifier, store the lexeme of the identifier in SVAL. If
2489 scanning a number, store its value in *IVAL. */
2492 xbm_scan (unsigned char **s
, unsigned char *end
, char *sval
, int *ival
)
2498 /* Skip white space. */
2499 while (*s
< end
&& (c
= *(*s
)++, c_isspace (c
)))
2504 else if (c_isdigit (c
))
2506 int value
= 0, digit
;
2508 if (c
== '0' && *s
< end
)
2511 if (c
== 'x' || c
== 'X')
2518 else if (c
>= 'a' && c
<= 'f')
2519 digit
= c
- 'a' + 10;
2520 else if (c
>= 'A' && c
<= 'F')
2521 digit
= c
- 'A' + 10;
2524 value
= 16 * value
+ digit
;
2527 else if (c_isdigit (c
))
2531 && (c
= *(*s
)++, c_isdigit (c
)))
2532 value
= 8 * value
+ c
- '0';
2539 && (c
= *(*s
)++, c_isdigit (c
)))
2540 value
= 10 * value
+ c
- '0';
2548 else if (c_isalpha (c
) || c
== '_')
2552 && (c
= *(*s
)++, (c_isalnum (c
) || c
== '_')))
2559 else if (c
== '/' && **s
== '*')
2561 /* C-style comment. */
2563 while (**s
&& (**s
!= '*' || *(*s
+ 1) != '/'))
2577 /* Create a Windows bitmap from X bitmap data. */
2579 w32_create_pixmap_from_bitmap_data (int width
, int height
, char *data
)
2581 static unsigned char swap_nibble
[16]
2582 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
2583 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
2584 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
2585 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
2587 unsigned char *bits
, *p
;
2590 w1
= (width
+ 7) / 8; /* nb of 8bits elt in X bitmap */
2591 w2
= ((width
+ 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
2592 bits
= alloca (height
* w2
);
2593 memset (bits
, 0, height
* w2
);
2594 for (i
= 0; i
< height
; i
++)
2597 for (j
= 0; j
< w1
; j
++)
2599 /* Bitswap XBM bytes to match how Windows does things. */
2600 unsigned char c
= *data
++;
2601 *p
++ = (unsigned char)((swap_nibble
[c
& 0xf] << 4)
2602 | (swap_nibble
[(c
>>4) & 0xf]));
2605 bmp
= CreateBitmap (width
, height
, 1, 1, (char *) bits
);
2611 convert_mono_to_color_image (struct frame
*f
, struct image
*img
,
2612 COLORREF foreground
, COLORREF background
)
2614 HDC hdc
, old_img_dc
, new_img_dc
;
2615 HGDIOBJ old_prev
, new_prev
;
2618 hdc
= get_frame_dc (f
);
2619 old_img_dc
= CreateCompatibleDC (hdc
);
2620 new_img_dc
= CreateCompatibleDC (hdc
);
2621 new_pixmap
= CreateCompatibleBitmap (hdc
, img
->width
, img
->height
);
2622 release_frame_dc (f
, hdc
);
2623 old_prev
= SelectObject (old_img_dc
, img
->pixmap
);
2624 new_prev
= SelectObject (new_img_dc
, new_pixmap
);
2625 /* Windows convention for mono bitmaps is black = background,
2626 white = foreground. */
2627 SetTextColor (new_img_dc
, background
);
2628 SetBkColor (new_img_dc
, foreground
);
2630 BitBlt (new_img_dc
, 0, 0, img
->width
, img
->height
, old_img_dc
,
2633 SelectObject (old_img_dc
, old_prev
);
2634 SelectObject (new_img_dc
, new_prev
);
2635 DeleteDC (old_img_dc
);
2636 DeleteDC (new_img_dc
);
2637 DeleteObject (img
->pixmap
);
2638 if (new_pixmap
== 0)
2639 fprintf (stderr
, "Failed to convert image to color.\n");
2641 img
->pixmap
= new_pixmap
;
2644 #define XBM_BIT_SHUFFLE(b) (~(b))
2648 #define XBM_BIT_SHUFFLE(b) (b)
2650 #endif /* HAVE_NTGUI */
2654 Create_Pixmap_From_Bitmap_Data (struct frame
*f
, struct image
*img
, char *data
,
2655 RGB_PIXEL_COLOR fg
, RGB_PIXEL_COLOR bg
,
2656 bool non_default_colors
)
2660 = w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
, data
);
2662 /* If colors were specified, transfer the bitmap to a color one. */
2663 if (non_default_colors
)
2664 convert_mono_to_color_image (f
, img
, fg
, bg
);
2666 #elif defined (HAVE_NS)
2667 img
->pixmap
= ns_image_from_XBM (data
, img
->width
, img
->height
);
2671 (x_check_image_size (0, img
->width
, img
->height
)
2672 ? XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
2675 img
->width
, img
->height
,
2677 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)))
2679 #endif /* !HAVE_NTGUI && !HAVE_NS */
2684 /* Replacement for XReadBitmapFileData which isn't available under old
2685 X versions. CONTENTS is a pointer to a buffer to parse; END is the
2686 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
2687 the image. Return in *DATA the bitmap data allocated with xmalloc.
2688 Value is true if successful. DATA null means just test if
2689 CONTENTS looks like an in-memory XBM file. If INHIBIT_IMAGE_ERROR,
2690 inhibit the call to image_error when the image size is invalid (the
2691 bitmap remains unread). */
2694 xbm_read_bitmap_data (struct frame
*f
, unsigned char *contents
, unsigned char *end
,
2695 int *width
, int *height
, char **data
,
2696 bool inhibit_image_error
)
2698 unsigned char *s
= contents
;
2699 char buffer
[BUFSIZ
];
2702 int bytes_per_line
, i
, nbytes
;
2708 LA1 = xbm_scan (&s, end, buffer, &value)
2710 #define expect(TOKEN) \
2713 if (LA1 != (TOKEN)) \
2719 #define expect_ident(IDENT) \
2720 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
2725 *width
= *height
= -1;
2728 LA1
= xbm_scan (&s
, end
, buffer
, &value
);
2730 /* Parse defines for width, height and hot-spots. */
2734 expect_ident ("define");
2735 expect (XBM_TK_IDENT
);
2737 if (LA1
== XBM_TK_NUMBER
)
2739 char *q
= strrchr (buffer
, '_');
2740 q
= q
? q
+ 1 : buffer
;
2741 if (strcmp (q
, "width") == 0)
2743 else if (strcmp (q
, "height") == 0)
2746 expect (XBM_TK_NUMBER
);
2749 if (!check_image_size (f
, *width
, *height
))
2751 if (!inhibit_image_error
)
2752 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
2755 else if (data
== NULL
)
2758 /* Parse bits. Must start with `static'. */
2759 expect_ident ("static");
2760 if (LA1
== XBM_TK_IDENT
)
2762 if (strcmp (buffer
, "unsigned") == 0)
2765 expect_ident ("char");
2767 else if (strcmp (buffer
, "short") == 0)
2771 if (*width
% 16 && *width
% 16 < 9)
2774 else if (strcmp (buffer
, "char") == 0)
2782 expect (XBM_TK_IDENT
);
2788 if (! x_check_image_size (0, *width
, *height
))
2790 if (!inhibit_image_error
)
2791 image_error ("Image too large (%dx%d)",
2792 make_number (*width
), make_number (*height
));
2795 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
2796 nbytes
= bytes_per_line
* *height
;
2797 p
= *data
= xmalloc (nbytes
);
2801 for (i
= 0; i
< nbytes
; i
+= 2)
2804 expect (XBM_TK_NUMBER
);
2806 *p
++ = XBM_BIT_SHUFFLE (val
);
2807 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
2808 *p
++ = XBM_BIT_SHUFFLE (value
>> 8);
2810 if (LA1
== ',' || LA1
== '}')
2818 for (i
= 0; i
< nbytes
; ++i
)
2821 expect (XBM_TK_NUMBER
);
2823 *p
++ = XBM_BIT_SHUFFLE (val
);
2825 if (LA1
== ',' || LA1
== '}')
2850 /* Load XBM image IMG which will be displayed on frame F from buffer
2851 CONTENTS. END is the end of the buffer. Value is true if
2855 xbm_load_image (struct frame
*f
, struct image
*img
, unsigned char *contents
,
2862 rc
= xbm_read_bitmap_data (f
, contents
, end
, &img
->width
, &img
->height
,
2866 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2867 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2868 bool non_default_colors
= 0;
2871 eassert (img
->width
> 0 && img
->height
> 0);
2873 /* Get foreground and background colors, maybe allocate colors. */
2874 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
2877 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
2878 non_default_colors
= 1;
2880 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
2883 background
= x_alloc_image_color (f
, img
, value
, background
);
2884 img
->background
= background
;
2885 img
->background_valid
= 1;
2886 non_default_colors
= 1;
2889 Create_Pixmap_From_Bitmap_Data (f
, img
, data
,
2890 foreground
, background
,
2891 non_default_colors
);
2894 if (img
->pixmap
== NO_PIXMAP
)
2896 x_clear_image (f
, img
);
2897 image_error ("Unable to create X pixmap for `%s'", img
->spec
, Qnil
);
2903 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
2909 /* Value is true if DATA looks like an in-memory XBM file. */
2912 xbm_file_p (Lisp_Object data
)
2915 return (STRINGP (data
)
2916 && xbm_read_bitmap_data (NULL
, SDATA (data
),
2917 (SDATA (data
) + SBYTES (data
)),
2922 /* Fill image IMG which is used on frame F with pixmap data. Value is
2923 true if successful. */
2926 xbm_load (struct frame
*f
, struct image
*img
)
2929 Lisp_Object file_name
;
2931 eassert (xbm_image_p (img
->spec
));
2933 /* If IMG->spec specifies a file name, create a non-file spec from it. */
2934 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
2935 if (STRINGP (file_name
))
2938 unsigned char *contents
;
2941 file
= x_find_image_file (file_name
);
2942 if (!STRINGP (file
))
2944 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
2948 contents
= slurp_file (SSDATA (file
), &size
);
2949 if (contents
== NULL
)
2951 image_error ("Error loading XBM image `%s'", img
->spec
, Qnil
);
2955 success_p
= xbm_load_image (f
, img
, contents
, contents
+ size
);
2960 struct image_keyword fmt
[XBM_LAST
];
2962 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2963 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2964 bool non_default_colors
= 0;
2967 bool in_memory_file_p
= 0;
2969 /* See if data looks like an in-memory XBM file. */
2970 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
2971 in_memory_file_p
= xbm_file_p (data
);
2973 /* Parse the image specification. */
2974 memcpy (fmt
, xbm_format
, sizeof fmt
);
2975 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
2978 /* Get specified width, and height. */
2979 if (!in_memory_file_p
)
2981 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
2982 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
2983 eassert (img
->width
> 0 && img
->height
> 0);
2984 if (!check_image_size (f
, img
->width
, img
->height
))
2986 image_error ("Invalid image size (see `max-image-size')",
2992 /* Get foreground and background colors, maybe allocate colors. */
2993 if (fmt
[XBM_FOREGROUND
].count
2994 && STRINGP (fmt
[XBM_FOREGROUND
].value
))
2996 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
2998 non_default_colors
= 1;
3001 if (fmt
[XBM_BACKGROUND
].count
3002 && STRINGP (fmt
[XBM_BACKGROUND
].value
))
3004 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
3006 non_default_colors
= 1;
3009 if (in_memory_file_p
)
3010 success_p
= xbm_load_image (f
, img
, SDATA (data
),
3019 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
3021 p
= bits
= alloca (nbytes
* img
->height
);
3022 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
3024 Lisp_Object line
= AREF (data
, i
);
3026 memcpy (p
, SDATA (line
), nbytes
);
3028 memcpy (p
, XBOOL_VECTOR (line
)->data
, nbytes
);
3031 else if (STRINGP (data
))
3032 bits
= SSDATA (data
);
3034 bits
= (char *) XBOOL_VECTOR (data
)->data
;
3040 /* Windows mono bitmaps are reversed compared with X. */
3041 invertedBits
= bits
;
3042 nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
3044 bits
= alloca (nbytes
);
3045 for (i
= 0; i
< nbytes
; i
++)
3046 bits
[i
] = XBM_BIT_SHUFFLE (invertedBits
[i
]);
3049 /* Create the pixmap. */
3051 if (x_check_image_size (0, img
->width
, img
->height
))
3052 Create_Pixmap_From_Bitmap_Data (f
, img
, bits
,
3053 foreground
, background
,
3054 non_default_colors
);
3056 img
->pixmap
= NO_PIXMAP
;
3062 image_error ("Unable to create pixmap for XBM image `%s'",
3064 x_clear_image (f
, img
);
3074 /***********************************************************************
3076 ***********************************************************************/
3078 #if defined (HAVE_XPM) || defined (HAVE_NS)
3080 static bool xpm_image_p (Lisp_Object object
);
3081 static bool xpm_load (struct frame
*f
, struct image
*img
);
3083 #endif /* HAVE_XPM || HAVE_NS */
3087 /* Indicate to xpm.h that we don't have Xlib. */
3089 /* simx.h in xpm defines XColor and XImage differently than Emacs. */
3090 /* It also defines Display the same way as Emacs, but gcc 3.3 still barfs. */
3091 #define XColor xpm_XColor
3092 #define XImage xpm_XImage
3093 #define Display xpm_Display
3094 #define PIXEL_ALREADY_TYPEDEFED
3095 #include "X11/xpm.h"
3100 #undef PIXEL_ALREADY_TYPEDEFED
3102 #include "X11/xpm.h"
3103 #endif /* HAVE_NTGUI */
3104 #endif /* HAVE_XPM */
3106 #if defined (HAVE_XPM) || defined (HAVE_NS)
3107 /* The symbol `xpm' identifying XPM-format images. */
3109 static Lisp_Object Qxpm
;
3111 /* Indices of image specification fields in xpm_format, below. */
3113 enum xpm_keyword_index
3129 /* Vector of image_keyword structures describing the format
3130 of valid XPM image specifications. */
3132 static const struct image_keyword xpm_format
[XPM_LAST
] =
3134 {":type", IMAGE_SYMBOL_VALUE
, 1},
3135 {":file", IMAGE_STRING_VALUE
, 0},
3136 {":data", IMAGE_STRING_VALUE
, 0},
3137 {":ascent", IMAGE_ASCENT_VALUE
, 0},
3138 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
3139 {":relief", IMAGE_INTEGER_VALUE
, 0},
3140 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3141 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3142 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3143 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3144 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
3147 #if defined HAVE_NTGUI && defined WINDOWSNT
3148 static bool init_xpm_functions (void);
3150 #define init_xpm_functions NULL
3153 /* Structure describing the image type XPM. */
3155 static struct image_type xpm_type
=
3165 #ifdef HAVE_X_WINDOWS
3167 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
3168 functions for allocating image colors. Our own functions handle
3169 color allocation failures more gracefully than the ones on the XPM
3172 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
3173 #define ALLOC_XPM_COLORS
3175 #endif /* HAVE_X_WINDOWS */
3177 #ifdef ALLOC_XPM_COLORS
3179 static struct xpm_cached_color
*xpm_cache_color (struct frame
*, char *,
3182 /* An entry in a hash table used to cache color definitions of named
3183 colors. This cache is necessary to speed up XPM image loading in
3184 case we do color allocations ourselves. Without it, we would need
3185 a call to XParseColor per pixel in the image. */
3187 struct xpm_cached_color
3189 /* Next in collision chain. */
3190 struct xpm_cached_color
*next
;
3192 /* Color definition (RGB and pixel color). */
3196 char name
[FLEXIBLE_ARRAY_MEMBER
];
3199 /* The hash table used for the color cache, and its bucket vector
3202 #define XPM_COLOR_CACHE_BUCKETS 1001
3203 static struct xpm_cached_color
**xpm_color_cache
;
3205 /* Initialize the color cache. */
3208 xpm_init_color_cache (struct frame
*f
, XpmAttributes
*attrs
)
3210 size_t nbytes
= XPM_COLOR_CACHE_BUCKETS
* sizeof *xpm_color_cache
;
3211 xpm_color_cache
= xzalloc (nbytes
);
3212 init_color_table ();
3214 if (attrs
->valuemask
& XpmColorSymbols
)
3219 for (i
= 0; i
< attrs
->numsymbols
; ++i
)
3220 if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
3221 attrs
->colorsymbols
[i
].value
, &color
))
3223 color
.pixel
= lookup_rgb_color (f
, color
.red
, color
.green
,
3225 xpm_cache_color (f
, attrs
->colorsymbols
[i
].name
, &color
, -1);
3230 /* Free the color cache. */
3233 xpm_free_color_cache (void)
3235 struct xpm_cached_color
*p
, *next
;
3238 for (i
= 0; i
< XPM_COLOR_CACHE_BUCKETS
; ++i
)
3239 for (p
= xpm_color_cache
[i
]; p
; p
= next
)
3245 xfree (xpm_color_cache
);
3246 xpm_color_cache
= NULL
;
3247 free_color_table ();
3250 /* Return the bucket index for color named COLOR_NAME in the color
3254 xpm_color_bucket (char *color_name
)
3256 EMACS_UINT hash
= hash_string (color_name
, strlen (color_name
));
3257 return hash
% XPM_COLOR_CACHE_BUCKETS
;
3261 /* On frame F, cache values COLOR for color with name COLOR_NAME.
3262 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
3265 static struct xpm_cached_color
*
3266 xpm_cache_color (struct frame
*f
, char *color_name
, XColor
*color
, int bucket
)
3269 struct xpm_cached_color
*p
;
3272 bucket
= xpm_color_bucket (color_name
);
3274 nbytes
= offsetof (struct xpm_cached_color
, name
) + strlen (color_name
) + 1;
3275 p
= xmalloc (nbytes
);
3276 strcpy (p
->name
, color_name
);
3278 p
->next
= xpm_color_cache
[bucket
];
3279 xpm_color_cache
[bucket
] = p
;
3283 /* Look up color COLOR_NAME for frame F in the color cache. If found,
3284 return the cached definition in *COLOR. Otherwise, make a new
3285 entry in the cache and allocate the color. Value is false if color
3286 allocation failed. */
3289 xpm_lookup_color (struct frame
*f
, char *color_name
, XColor
*color
)
3291 struct xpm_cached_color
*p
;
3292 int h
= xpm_color_bucket (color_name
);
3294 for (p
= xpm_color_cache
[h
]; p
; p
= p
->next
)
3295 if (strcmp (p
->name
, color_name
) == 0)
3300 else if (XParseColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
3303 color
->pixel
= lookup_rgb_color (f
, color
->red
, color
->green
,
3305 p
= xpm_cache_color (f
, color_name
, color
, h
);
3307 /* You get `opaque' at least from ImageMagick converting pbm to xpm
3308 with transparency, and it's useful. */
3309 else if (strcmp ("opaque", color_name
) == 0)
3311 memset (color
, 0, sizeof (XColor
)); /* Is this necessary/correct? */
3312 color
->pixel
= FRAME_FOREGROUND_PIXEL (f
);
3313 p
= xpm_cache_color (f
, color_name
, color
, h
);
3320 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
3321 CLOSURE is a pointer to the frame on which we allocate the
3322 color. Return in *COLOR the allocated color. Value is non-zero
3326 xpm_alloc_color (Display
*dpy
, Colormap cmap
, char *color_name
, XColor
*color
,
3329 return xpm_lookup_color (closure
, color_name
, color
);
3333 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
3334 is a pointer to the frame on which we allocate the color. Value is
3335 non-zero if successful. */
3338 xpm_free_colors (Display
*dpy
, Colormap cmap
, Pixel
*pixels
, int npixels
, void *closure
)
3343 #endif /* ALLOC_XPM_COLORS */
3348 /* XPM library details. */
3350 DEF_IMGLIB_FN (void, XpmFreeAttributes
, (XpmAttributes
*));
3351 DEF_IMGLIB_FN (int, XpmCreateImageFromBuffer
, (Display
*, char *, xpm_XImage
**,
3352 xpm_XImage
**, XpmAttributes
*));
3353 DEF_IMGLIB_FN (int, XpmReadFileToImage
, (Display
*, char *, xpm_XImage
**,
3354 xpm_XImage
**, XpmAttributes
*));
3355 DEF_IMGLIB_FN (void, XImageFree
, (xpm_XImage
*));
3358 init_xpm_functions (void)
3362 if (!(library
= w32_delayed_load (Qxpm
)))
3365 LOAD_IMGLIB_FN (library
, XpmFreeAttributes
);
3366 LOAD_IMGLIB_FN (library
, XpmCreateImageFromBuffer
);
3367 LOAD_IMGLIB_FN (library
, XpmReadFileToImage
);
3368 LOAD_IMGLIB_FN (library
, XImageFree
);
3372 #endif /* WINDOWSNT */
3374 #if defined HAVE_NTGUI && !defined WINDOWSNT
3375 /* Glue for code below */
3376 #define fn_XpmReadFileToImage XpmReadFileToImage
3377 #define fn_XpmCreateImageFromBuffer XpmCreateImageFromBuffer
3378 #define fn_XImageFree XImageFree
3379 #define fn_XpmFreeAttributes XpmFreeAttributes
3380 #endif /* HAVE_NTGUI && !WINDOWSNT */
3382 /* Value is true if COLOR_SYMBOLS is a valid color symbols list
3383 for XPM images. Such a list must consist of conses whose car and
3387 xpm_valid_color_symbols_p (Lisp_Object color_symbols
)
3389 while (CONSP (color_symbols
))
3391 Lisp_Object sym
= XCAR (color_symbols
);
3393 || !STRINGP (XCAR (sym
))
3394 || !STRINGP (XCDR (sym
)))
3396 color_symbols
= XCDR (color_symbols
);
3399 return NILP (color_symbols
);
3403 /* Value is true if OBJECT is a valid XPM image specification. */
3406 xpm_image_p (Lisp_Object object
)
3408 struct image_keyword fmt
[XPM_LAST
];
3409 memcpy (fmt
, xpm_format
, sizeof fmt
);
3410 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
3411 /* Either `:file' or `:data' must be present. */
3412 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
3413 /* Either no `:color-symbols' or it's a list of conses
3414 whose car and cdr are strings. */
3415 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
3416 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
)));
3419 #endif /* HAVE_XPM || HAVE_NS */
3421 #if defined HAVE_XPM && defined HAVE_X_WINDOWS && !defined USE_GTK
3423 x_create_bitmap_from_xpm_data (struct frame
*f
, const char **bits
)
3425 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
3428 XpmAttributes attrs
;
3429 Pixmap bitmap
, mask
;
3431 memset (&attrs
, 0, sizeof attrs
);
3433 attrs
.visual
= FRAME_X_VISUAL (f
);
3434 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3435 attrs
.valuemask
|= XpmVisual
;
3436 attrs
.valuemask
|= XpmColormap
;
3438 rc
= XpmCreatePixmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3439 (char **) bits
, &bitmap
, &mask
, &attrs
);
3440 if (rc
!= XpmSuccess
)
3442 XpmFreeAttributes (&attrs
);
3446 id
= x_allocate_bitmap_record (f
);
3447 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
3448 dpyinfo
->bitmaps
[id
- 1].have_mask
= 1;
3449 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
3450 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
3451 dpyinfo
->bitmaps
[id
- 1].height
= attrs
.height
;
3452 dpyinfo
->bitmaps
[id
- 1].width
= attrs
.width
;
3453 dpyinfo
->bitmaps
[id
- 1].depth
= attrs
.depth
;
3454 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
3456 XpmFreeAttributes (&attrs
);
3459 #endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */
3461 /* Load image IMG which will be displayed on frame F. Value is
3462 true if successful. */
3467 xpm_load (struct frame
*f
, struct image
*img
)
3470 XpmAttributes attrs
;
3471 Lisp_Object specified_file
, color_symbols
;
3474 xpm_XImage
* xpm_image
= NULL
, * xpm_mask
= NULL
;
3475 #endif /* HAVE_NTGUI */
3477 /* Configure the XPM lib. Use the visual of frame F. Allocate
3478 close colors. Return colors allocated. */
3479 memset (&attrs
, 0, sizeof attrs
);
3482 attrs
.visual
= FRAME_X_VISUAL (f
);
3483 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3484 attrs
.valuemask
|= XpmVisual
;
3485 attrs
.valuemask
|= XpmColormap
;
3486 #endif /* HAVE_NTGUI */
3488 #ifdef ALLOC_XPM_COLORS
3489 /* Allocate colors with our own functions which handle
3490 failing color allocation more gracefully. */
3491 attrs
.color_closure
= f
;
3492 attrs
.alloc_color
= xpm_alloc_color
;
3493 attrs
.free_colors
= xpm_free_colors
;
3494 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
3495 #else /* not ALLOC_XPM_COLORS */
3496 /* Let the XPM lib allocate colors. */
3497 attrs
.valuemask
|= XpmReturnAllocPixels
;
3498 #ifdef XpmAllocCloseColors
3499 attrs
.alloc_close_colors
= 1;
3500 attrs
.valuemask
|= XpmAllocCloseColors
;
3501 #else /* not XpmAllocCloseColors */
3502 attrs
.closeness
= 600;
3503 attrs
.valuemask
|= XpmCloseness
;
3504 #endif /* not XpmAllocCloseColors */
3505 #endif /* ALLOC_XPM_COLORS */
3507 /* If image specification contains symbolic color definitions, add
3508 these to `attrs'. */
3509 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
3510 if (CONSP (color_symbols
))
3513 XpmColorSymbol
*xpm_syms
;
3516 attrs
.valuemask
|= XpmColorSymbols
;
3518 /* Count number of symbols. */
3519 attrs
.numsymbols
= 0;
3520 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
3523 /* Allocate an XpmColorSymbol array. */
3524 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
3525 xpm_syms
= alloca (size
);
3526 memset (xpm_syms
, 0, size
);
3527 attrs
.colorsymbols
= xpm_syms
;
3529 /* Fill the color symbol array. */
3530 for (tail
= color_symbols
, i
= 0;
3532 ++i
, tail
= XCDR (tail
))
3536 char *empty_string
= (char *) "";
3538 if (!CONSP (XCAR (tail
)))
3540 xpm_syms
[i
].name
= empty_string
;
3541 xpm_syms
[i
].value
= empty_string
;
3544 name
= XCAR (XCAR (tail
));
3545 color
= XCDR (XCAR (tail
));
3548 xpm_syms
[i
].name
= alloca (SCHARS (name
) + 1);
3549 strcpy (xpm_syms
[i
].name
, SSDATA (name
));
3552 xpm_syms
[i
].name
= empty_string
;
3553 if (STRINGP (color
))
3555 xpm_syms
[i
].value
= alloca (SCHARS (color
) + 1);
3556 strcpy (xpm_syms
[i
].value
, SSDATA (color
));
3559 xpm_syms
[i
].value
= empty_string
;
3563 /* Create a pixmap for the image, either from a file, or from a
3564 string buffer containing data in the same format as an XPM file. */
3565 #ifdef ALLOC_XPM_COLORS
3566 xpm_init_color_cache (f
, &attrs
);
3569 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
3573 HDC frame_dc
= get_frame_dc (f
);
3574 hdc
= CreateCompatibleDC (frame_dc
);
3575 release_frame_dc (f
, frame_dc
);
3577 #endif /* HAVE_NTGUI */
3579 if (STRINGP (specified_file
))
3581 Lisp_Object file
= x_find_image_file (specified_file
);
3582 if (!STRINGP (file
))
3584 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
3585 #ifdef ALLOC_XPM_COLORS
3586 xpm_free_color_cache ();
3592 /* XpmReadFileToPixmap is not available in the Windows port of
3593 libxpm. But XpmReadFileToImage almost does what we want. */
3594 rc
= fn_XpmReadFileToImage (&hdc
, SDATA (file
),
3595 &xpm_image
, &xpm_mask
,
3598 rc
= XpmReadFileToImage (FRAME_X_DISPLAY (f
), SSDATA (file
),
3599 &img
->ximg
, &img
->mask_img
,
3601 #endif /* HAVE_NTGUI */
3605 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
3606 if (!STRINGP (buffer
))
3608 image_error ("Invalid image data `%s'", buffer
, Qnil
);
3609 #ifdef ALLOC_XPM_COLORS
3610 xpm_free_color_cache ();
3615 /* XpmCreatePixmapFromBuffer is not available in the Windows port
3616 of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
3617 rc
= fn_XpmCreateImageFromBuffer (&hdc
, SDATA (buffer
),
3618 &xpm_image
, &xpm_mask
,
3621 rc
= XpmCreateImageFromBuffer (FRAME_X_DISPLAY (f
), SSDATA (buffer
),
3622 &img
->ximg
, &img
->mask_img
,
3624 #endif /* HAVE_NTGUI */
3627 #ifdef HAVE_X_WINDOWS
3628 if (rc
== XpmSuccess
)
3630 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3631 img
->ximg
->width
, img
->ximg
->height
,
3633 if (img
->pixmap
== NO_PIXMAP
)
3635 x_clear_image (f
, img
);
3638 else if (img
->mask_img
)
3640 img
->mask
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3641 img
->mask_img
->width
,
3642 img
->mask_img
->height
,
3643 img
->mask_img
->depth
);
3644 if (img
->mask
== NO_PIXMAP
)
3646 x_clear_image (f
, img
);
3653 if (rc
== XpmSuccess
)
3655 #if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS)
3656 img
->colors
= colors_in_color_table (&img
->ncolors
);
3657 #else /* not ALLOC_XPM_COLORS */
3661 /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
3662 plus some duplicate attributes. */
3663 if (xpm_image
&& xpm_image
->bitmap
)
3665 img
->pixmap
= xpm_image
->bitmap
;
3666 /* XImageFree in libXpm frees XImage struct without destroying
3667 the bitmap, which is what we want. */
3668 fn_XImageFree (xpm_image
);
3670 if (xpm_mask
&& xpm_mask
->bitmap
)
3672 /* The mask appears to be inverted compared with what we expect.
3673 TODO: invert our expectations. See other places where we
3674 have to invert bits because our idea of masks is backwards. */
3676 old_obj
= SelectObject (hdc
, xpm_mask
->bitmap
);
3678 PatBlt (hdc
, 0, 0, xpm_mask
->width
, xpm_mask
->height
, DSTINVERT
);
3679 SelectObject (hdc
, old_obj
);
3681 img
->mask
= xpm_mask
->bitmap
;
3682 fn_XImageFree (xpm_mask
);
3687 #endif /* HAVE_NTGUI */
3689 /* Remember allocated colors. */
3690 img
->colors
= xnmalloc (attrs
.nalloc_pixels
, sizeof *img
->colors
);
3691 img
->ncolors
= attrs
.nalloc_pixels
;
3692 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
3694 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
3695 #ifdef DEBUG_X_COLORS
3696 register_color (img
->colors
[i
]);
3699 #endif /* not ALLOC_XPM_COLORS */
3701 img
->width
= attrs
.width
;
3702 img
->height
= attrs
.height
;
3703 eassert (img
->width
> 0 && img
->height
> 0);
3705 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
3707 fn_XpmFreeAttributes (&attrs
);
3709 XpmFreeAttributes (&attrs
);
3710 #endif /* HAVE_NTGUI */
3712 #ifdef HAVE_X_WINDOWS
3713 /* Maybe fill in the background field while we have ximg handy. */
3714 IMAGE_BACKGROUND (img
, f
, img
->ximg
);
3716 /* Fill in the background_transparent field while we have the
3718 image_background_transparent (img
, f
, img
->mask_img
);
3725 #endif /* HAVE_NTGUI */
3730 image_error ("Error opening XPM file (%s)", img
->spec
, Qnil
);
3733 case XpmFileInvalid
:
3734 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
3738 image_error ("Out of memory (%s)", img
->spec
, Qnil
);
3741 case XpmColorFailed
:
3742 image_error ("Color allocation error (%s)", img
->spec
, Qnil
);
3746 image_error ("Unknown error (%s)", img
->spec
, Qnil
);
3751 #ifdef ALLOC_XPM_COLORS
3752 xpm_free_color_cache ();
3754 return rc
== XpmSuccess
;
3757 #endif /* HAVE_XPM */
3759 #if defined (HAVE_NS) && !defined (HAVE_XPM)
3761 /* XPM support functions for NS where libxpm is not available.
3762 Only XPM version 3 (without any extensions) is supported. */
3764 static void xpm_put_color_table_v (Lisp_Object
, const unsigned char *,
3766 static Lisp_Object
xpm_get_color_table_v (Lisp_Object
,
3767 const unsigned char *, int);
3768 static void xpm_put_color_table_h (Lisp_Object
, const unsigned char *,
3770 static Lisp_Object
xpm_get_color_table_h (Lisp_Object
,
3771 const unsigned char *, int);
3773 /* Tokens returned from xpm_scan. */
3782 /* Scan an XPM data and return a character (< 256) or a token defined
3783 by enum xpm_token above. *S and END are the start (inclusive) and
3784 the end (exclusive) addresses of the data, respectively. Advance
3785 *S while scanning. If token is either XPM_TK_IDENT or
3786 XPM_TK_STRING, *BEG and *LEN are set to the start address and the
3787 length of the corresponding token, respectively. */
3790 xpm_scan (const unsigned char **s
,
3791 const unsigned char *end
,
3792 const unsigned char **beg
,
3799 /* Skip white-space. */
3800 while (*s
< end
&& (c
= *(*s
)++, c_isspace (c
)))
3803 /* gnus-pointer.xpm uses '-' in its identifier.
3804 sb-dir-plus.xpm uses '+' in its identifier. */
3805 if (c_isalpha (c
) || c
== '_' || c
== '-' || c
== '+')
3809 && (c
= **s
, c_isalnum (c
)
3810 || c
== '_' || c
== '-' || c
== '+'))
3813 return XPM_TK_IDENT
;
3818 while (*s
< end
&& **s
!= '"')
3823 return XPM_TK_STRING
;
3827 if (*s
< end
&& **s
== '*')
3829 /* C-style comment. */
3833 while (*s
< end
&& *(*s
)++ != '*')
3836 while (*s
< end
&& **s
!= '/');
3850 /* Functions for color table lookup in XPM data. A key is a string
3851 specifying the color of each pixel in XPM data. A value is either
3852 an integer that specifies a pixel color, Qt that specifies
3853 transparency, or Qnil for the unspecified color. If the length of
3854 the key string is one, a vector is used as a table. Otherwise, a
3855 hash table is used. */
3858 xpm_make_color_table_v (void (**put_func
) (Lisp_Object
,
3859 const unsigned char *,
3862 Lisp_Object (**get_func
) (Lisp_Object
,
3863 const unsigned char *,
3866 *put_func
= xpm_put_color_table_v
;
3867 *get_func
= xpm_get_color_table_v
;
3868 return Fmake_vector (make_number (256), Qnil
);
3872 xpm_put_color_table_v (Lisp_Object color_table
,
3873 const unsigned char *chars_start
,
3877 ASET (color_table
, *chars_start
, color
);
3881 xpm_get_color_table_v (Lisp_Object color_table
,
3882 const unsigned char *chars_start
,
3885 return AREF (color_table
, *chars_start
);
3889 xpm_make_color_table_h (void (**put_func
) (Lisp_Object
,
3890 const unsigned char *,
3893 Lisp_Object (**get_func
) (Lisp_Object
,
3894 const unsigned char *,
3897 *put_func
= xpm_put_color_table_h
;
3898 *get_func
= xpm_get_color_table_h
;
3899 return make_hash_table (hashtest_equal
, make_number (DEFAULT_HASH_SIZE
),
3900 make_float (DEFAULT_REHASH_SIZE
),
3901 make_float (DEFAULT_REHASH_THRESHOLD
),
3906 xpm_put_color_table_h (Lisp_Object color_table
,
3907 const unsigned char *chars_start
,
3911 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
3912 EMACS_UINT hash_code
;
3913 Lisp_Object chars
= make_unibyte_string (chars_start
, chars_len
);
3915 hash_lookup (table
, chars
, &hash_code
);
3916 hash_put (table
, chars
, color
, hash_code
);
3920 xpm_get_color_table_h (Lisp_Object color_table
,
3921 const unsigned char *chars_start
,
3924 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
3926 hash_lookup (table
, make_unibyte_string (chars_start
, chars_len
), NULL
);
3928 return i
>= 0 ? HASH_VALUE (table
, i
) : Qnil
;
3931 enum xpm_color_key
{
3939 static const char xpm_color_key_strings
[][4] = {"s", "m", "g4", "g", "c"};
3942 xpm_str_to_color_key (const char *s
)
3947 i
< sizeof xpm_color_key_strings
/ sizeof xpm_color_key_strings
[0];
3949 if (strcmp (xpm_color_key_strings
[i
], s
) == 0)
3955 xpm_load_image (struct frame
*f
,
3957 const unsigned char *contents
,
3958 const unsigned char *end
)
3960 const unsigned char *s
= contents
, *beg
, *str
;
3961 unsigned char buffer
[BUFSIZ
];
3962 int width
, height
, x
, y
;
3963 int num_colors
, chars_per_pixel
;
3966 void (*put_color_table
) (Lisp_Object
, const unsigned char *, int, Lisp_Object
);
3967 Lisp_Object (*get_color_table
) (Lisp_Object
, const unsigned char *, int);
3968 Lisp_Object frame
, color_symbols
, color_table
;
3971 XImagePtr ximg
= NULL
, mask_img
= NULL
;
3974 LA1 = xpm_scan (&s, end, &beg, &len)
3976 #define expect(TOKEN) \
3979 if (LA1 != (TOKEN)) \
3985 #define expect_ident(IDENT) \
3986 if (LA1 == XPM_TK_IDENT \
3987 && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
3992 if (!(end
- s
>= 9 && memcmp (s
, "/* XPM */", 9) == 0))
3996 expect_ident ("static");
3997 expect_ident ("char");
3999 expect (XPM_TK_IDENT
);
4004 expect (XPM_TK_STRING
);
4007 memcpy (buffer
, beg
, len
);
4009 if (sscanf (buffer
, "%d %d %d %d", &width
, &height
,
4010 &num_colors
, &chars_per_pixel
) != 4
4011 || width
<= 0 || height
<= 0
4012 || num_colors
<= 0 || chars_per_pixel
<= 0)
4015 if (!check_image_size (f
, width
, height
))
4017 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
4021 if (!image_create_x_image_and_pixmap (f
, img
, width
, height
, 0, &ximg
, 0)
4023 || !image_create_x_image_and_pixmap (f
, img
, width
, height
, 1,
4028 image_error ("Image too large", Qnil
, Qnil
);
4034 XSETFRAME (frame
, f
);
4035 if (!NILP (Fxw_display_color_p (frame
)))
4036 best_key
= XPM_COLOR_KEY_C
;
4037 else if (!NILP (Fx_display_grayscale_p (frame
)))
4038 best_key
= (XFASTINT (Fx_display_planes (frame
)) > 2
4039 ? XPM_COLOR_KEY_G
: XPM_COLOR_KEY_G4
);
4041 best_key
= XPM_COLOR_KEY_M
;
4043 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
4044 if (chars_per_pixel
== 1)
4045 color_table
= xpm_make_color_table_v (&put_color_table
,
4048 color_table
= xpm_make_color_table_h (&put_color_table
,
4051 while (num_colors
-- > 0)
4053 char *color
, *max_color
;
4054 int key
, next_key
, max_key
= 0;
4055 Lisp_Object symbol_color
= Qnil
, color_val
;
4058 expect (XPM_TK_STRING
);
4059 if (len
<= chars_per_pixel
|| len
>= BUFSIZ
+ chars_per_pixel
)
4061 memcpy (buffer
, beg
+ chars_per_pixel
, len
- chars_per_pixel
);
4062 buffer
[len
- chars_per_pixel
] = '\0';
4064 str
= strtok (buffer
, " \t");
4067 key
= xpm_str_to_color_key (str
);
4072 color
= strtok (NULL
, " \t");
4076 while ((str
= strtok (NULL
, " \t")) != NULL
)
4078 next_key
= xpm_str_to_color_key (str
);
4081 color
[strlen (color
)] = ' ';
4084 if (key
== XPM_COLOR_KEY_S
)
4086 if (NILP (symbol_color
))
4087 symbol_color
= build_string (color
);
4089 else if (max_key
< key
&& key
<= best_key
)
4099 if (!NILP (color_symbols
) && !NILP (symbol_color
))
4101 Lisp_Object specified_color
= Fassoc (symbol_color
, color_symbols
);
4103 if (CONSP (specified_color
) && STRINGP (XCDR (specified_color
)))
4105 if (xstrcasecmp (SSDATA (XCDR (specified_color
)), "None") == 0)
4107 else if (x_defined_color (f
, SSDATA (XCDR (specified_color
)),
4109 color_val
= make_number (cdef
.pixel
);
4112 if (NILP (color_val
) && max_key
> 0)
4114 if (xstrcasecmp (max_color
, "None") == 0)
4116 else if (x_defined_color (f
, max_color
, &cdef
, 0))
4117 color_val
= make_number (cdef
.pixel
);
4119 if (!NILP (color_val
))
4120 (*put_color_table
) (color_table
, beg
, chars_per_pixel
, color_val
);
4125 for (y
= 0; y
< height
; y
++)
4127 expect (XPM_TK_STRING
);
4129 if (len
< width
* chars_per_pixel
)
4131 for (x
= 0; x
< width
; x
++, str
+= chars_per_pixel
)
4133 Lisp_Object color_val
=
4134 (*get_color_table
) (color_table
, str
, chars_per_pixel
);
4136 XPutPixel (ximg
, x
, y
,
4137 (INTEGERP (color_val
) ? XINT (color_val
)
4138 : FRAME_FOREGROUND_PIXEL (f
)));
4140 XPutPixel (mask_img
, x
, y
,
4141 (!EQ (color_val
, Qt
) ? PIX_MASK_DRAW
4142 : (have_mask
= 1, PIX_MASK_RETAIN
)));
4144 if (EQ (color_val
, Qt
))
4145 ns_set_alpha (ximg
, x
, y
, 0);
4153 img
->height
= height
;
4155 /* Maybe fill in the background field while we have ximg handy. */
4156 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
4157 IMAGE_BACKGROUND (img
, f
, ximg
);
4159 image_put_x_image (f
, img
, ximg
, 0);
4163 /* Fill in the background_transparent field while we have the
4165 image_background_transparent (img
, f
, mask_img
);
4167 image_put_x_image (f
, img
, mask_img
, 1);
4171 x_destroy_x_image (mask_img
);
4172 x_clear_image_1 (f
, img
, CLEAR_IMAGE_MASK
);
4178 image_error ("Invalid XPM file (%s)", img
->spec
, Qnil
);
4179 x_destroy_x_image (ximg
);
4180 x_destroy_x_image (mask_img
);
4181 x_clear_image (f
, img
);
4190 xpm_load (struct frame
*f
,
4194 Lisp_Object file_name
;
4196 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4197 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
4198 if (STRINGP (file_name
))
4201 unsigned char *contents
;
4204 file
= x_find_image_file (file_name
);
4205 if (!STRINGP (file
))
4207 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
4211 contents
= slurp_file (SSDATA (file
), &size
);
4212 if (contents
== NULL
)
4214 image_error ("Error loading XPM image `%s'", img
->spec
, Qnil
);
4218 success_p
= xpm_load_image (f
, img
, contents
, contents
+ size
);
4225 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
4226 if (!STRINGP (data
))
4228 image_error ("Invalid image data `%s'", data
, Qnil
);
4231 success_p
= xpm_load_image (f
, img
, SDATA (data
),
4232 SDATA (data
) + SBYTES (data
));
4238 #endif /* HAVE_NS && !HAVE_XPM */
4242 /***********************************************************************
4244 ***********************************************************************/
4246 #ifdef COLOR_TABLE_SUPPORT
4248 /* An entry in the color table mapping an RGB color to a pixel color. */
4253 unsigned long pixel
;
4255 /* Next in color table collision list. */
4256 struct ct_color
*next
;
4259 /* The bucket vector size to use. Must be prime. */
4263 /* Value is a hash of the RGB color given by R, G, and B. */
4265 #define CT_HASH_RGB(R, G, B) (((R) << 16) ^ ((G) << 8) ^ (B))
4267 /* The color hash table. */
4269 static struct ct_color
**ct_table
;
4271 /* Number of entries in the color table. */
4273 static int ct_colors_allocated
;
4276 ct_colors_allocated_max
=
4278 min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof (unsigned long))
4281 /* Initialize the color table. */
4284 init_color_table (void)
4286 int size
= CT_SIZE
* sizeof (*ct_table
);
4287 ct_table
= xzalloc (size
);
4288 ct_colors_allocated
= 0;
4292 /* Free memory associated with the color table. */
4295 free_color_table (void)
4298 struct ct_color
*p
, *next
;
4300 for (i
= 0; i
< CT_SIZE
; ++i
)
4301 for (p
= ct_table
[i
]; p
; p
= next
)
4312 /* Value is a pixel color for RGB color R, G, B on frame F. If an
4313 entry for that color already is in the color table, return the
4314 pixel color of that entry. Otherwise, allocate a new color for R,
4315 G, B, and make an entry in the color table. */
4317 static unsigned long
4318 lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
)
4320 unsigned hash
= CT_HASH_RGB (r
, g
, b
);
4321 int i
= hash
% CT_SIZE
;
4323 Display_Info
*dpyinfo
;
4325 /* Handle TrueColor visuals specially, which improves performance by
4326 two orders of magnitude. Freeing colors on TrueColor visuals is
4327 a nop, and pixel colors specify RGB values directly. See also
4328 the Xlib spec, chapter 3.1. */
4329 dpyinfo
= FRAME_DISPLAY_INFO (f
);
4330 if (dpyinfo
->red_bits
> 0)
4332 unsigned long pr
, pg
, pb
;
4334 /* Apply gamma-correction like normal color allocation does. */
4338 color
.red
= r
, color
.green
= g
, color
.blue
= b
;
4339 gamma_correct (f
, &color
);
4340 r
= color
.red
, g
= color
.green
, b
= color
.blue
;
4343 /* Scale down RGB values to the visual's bits per RGB, and shift
4344 them to the right position in the pixel color. Note that the
4345 original RGB values are 16-bit values, as usual in X. */
4346 pr
= (r
>> (16 - dpyinfo
->red_bits
)) << dpyinfo
->red_offset
;
4347 pg
= (g
>> (16 - dpyinfo
->green_bits
)) << dpyinfo
->green_offset
;
4348 pb
= (b
>> (16 - dpyinfo
->blue_bits
)) << dpyinfo
->blue_offset
;
4350 /* Assemble the pixel color. */
4351 return pr
| pg
| pb
;
4354 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4355 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
4361 #ifdef HAVE_X_WINDOWS
4369 if (ct_colors_allocated_max
<= ct_colors_allocated
)
4370 return FRAME_FOREGROUND_PIXEL (f
);
4372 #ifdef HAVE_X_WINDOWS
4377 cmap
= FRAME_X_COLORMAP (f
);
4378 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4381 ++ct_colors_allocated
;
4382 p
= xmalloc (sizeof *p
);
4386 p
->pixel
= color
.pixel
;
4387 p
->next
= ct_table
[i
];
4391 return FRAME_FOREGROUND_PIXEL (f
);
4395 color
= PALETTERGB (r
, g
, b
);
4397 color
= RGB_TO_ULONG (r
, g
, b
);
4398 #endif /* HAVE_NTGUI */
4399 ++ct_colors_allocated
;
4400 p
= xmalloc (sizeof *p
);
4405 p
->next
= ct_table
[i
];
4407 #endif /* HAVE_X_WINDOWS */
4415 /* Look up pixel color PIXEL which is used on frame F in the color
4416 table. If not already present, allocate it. Value is PIXEL. */
4418 static unsigned long
4419 lookup_pixel_color (struct frame
*f
, unsigned long pixel
)
4421 int i
= pixel
% CT_SIZE
;
4424 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4425 if (p
->pixel
== pixel
)
4434 if (ct_colors_allocated_max
<= ct_colors_allocated
)
4435 return FRAME_FOREGROUND_PIXEL (f
);
4437 #ifdef HAVE_X_WINDOWS
4438 cmap
= FRAME_X_COLORMAP (f
);
4439 color
.pixel
= pixel
;
4440 x_query_color (f
, &color
);
4441 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4444 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
4445 color
.pixel
= pixel
;
4446 XQueryColor (NULL
, cmap
, &color
);
4447 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4449 #endif /* HAVE_X_WINDOWS */
4453 ++ct_colors_allocated
;
4455 p
= xmalloc (sizeof *p
);
4460 p
->next
= ct_table
[i
];
4464 return FRAME_FOREGROUND_PIXEL (f
);
4470 /* Value is a vector of all pixel colors contained in the color table,
4471 allocated via xmalloc. Set *N to the number of colors. */
4473 static unsigned long *
4474 colors_in_color_table (int *n
)
4478 unsigned long *colors
;
4480 if (ct_colors_allocated
== 0)
4487 colors
= xmalloc (ct_colors_allocated
* sizeof *colors
);
4488 *n
= ct_colors_allocated
;
4490 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
4491 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4492 colors
[j
++] = p
->pixel
;
4498 #else /* COLOR_TABLE_SUPPORT */
4500 static unsigned long
4501 lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
)
4503 unsigned long pixel
;
4506 pixel
= PALETTERGB (r
>> 8, g
>> 8, b
>> 8);
4507 #endif /* HAVE_NTGUI */
4510 pixel
= RGB_TO_ULONG (r
>> 8, g
>> 8, b
>> 8);
4511 #endif /* HAVE_NS */
4516 init_color_table (void)
4519 #endif /* COLOR_TABLE_SUPPORT */
4522 /***********************************************************************
4524 ***********************************************************************/
4526 /* Edge detection matrices for different edge-detection
4529 static int emboss_matrix
[9] = {
4531 2, -1, 0, /* y - 1 */
4533 0, 1, -2 /* y + 1 */
4536 static int laplace_matrix
[9] = {
4538 1, 0, 0, /* y - 1 */
4540 0, 0, -1 /* y + 1 */
4543 /* Value is the intensity of the color whose red/green/blue values
4546 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
4549 /* On frame F, return an array of XColor structures describing image
4550 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
4551 means also fill the red/green/blue members of the XColor
4552 structures. Value is a pointer to the array of XColors structures,
4553 allocated with xmalloc; it must be freed by the caller. */
4556 x_to_xcolors (struct frame
*f
, struct image
*img
, bool rgb_p
)
4560 XImagePtr_or_DC ximg
;
4563 #endif /* HAVE_NTGUI */
4565 if (min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *colors
/ img
->width
< img
->height
)
4566 memory_full (SIZE_MAX
);
4567 colors
= xmalloc (sizeof *colors
* img
->width
* img
->height
);
4569 /* Get the X image or create a memory device context for IMG. */
4570 ximg
= image_get_x_image_or_dc (f
, img
, 0, &prev
);
4572 /* Fill the `pixel' members of the XColor array. I wished there
4573 were an easy and portable way to circumvent XGetPixel. */
4575 for (y
= 0; y
< img
->height
; ++y
)
4577 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
4579 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4580 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4582 x_query_colors (f
, row
, img
->width
);
4586 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4588 /* W32_TODO: palette support needed here? */
4589 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4592 p
->red
= RED16_FROM_ULONG (p
->pixel
);
4593 p
->green
= GREEN16_FROM_ULONG (p
->pixel
);
4594 p
->blue
= BLUE16_FROM_ULONG (p
->pixel
);
4597 #endif /* HAVE_X_WINDOWS */
4600 image_unget_x_image_or_dc (img
, 0, ximg
, prev
);
4607 /* Put a pixel of COLOR at position X, Y in XIMG. XIMG must have been
4608 created with CreateDIBSection, with the pointer to the bit values
4609 stored in ximg->data. */
4612 XPutPixel (XImagePtr ximg
, int x
, int y
, COLORREF color
)
4614 int width
= ximg
->info
.bmiHeader
.biWidth
;
4615 unsigned char * pixel
;
4617 /* True color images. */
4618 if (ximg
->info
.bmiHeader
.biBitCount
== 24)
4620 int rowbytes
= width
* 3;
4621 /* Ensure scanlines are aligned on 4 byte boundaries. */
4623 rowbytes
+= 4 - (rowbytes
% 4);
4625 pixel
= ximg
->data
+ y
* rowbytes
+ x
* 3;
4626 /* Windows bitmaps are in BGR order. */
4627 *pixel
= GetBValue (color
);
4628 *(pixel
+ 1) = GetGValue (color
);
4629 *(pixel
+ 2) = GetRValue (color
);
4631 /* Monochrome images. */
4632 else if (ximg
->info
.bmiHeader
.biBitCount
== 1)
4634 int rowbytes
= width
/ 8;
4635 /* Ensure scanlines are aligned on 4 byte boundaries. */
4637 rowbytes
+= 4 - (rowbytes
% 4);
4638 pixel
= ximg
->data
+ y
* rowbytes
+ x
/ 8;
4639 /* Filter out palette info. */
4640 if (color
& 0x00ffffff)
4641 *pixel
= *pixel
| (1 << x
% 8);
4643 *pixel
= *pixel
& ~(1 << x
% 8);
4646 image_error ("XPutPixel: palette image not supported", Qnil
, Qnil
);
4649 #endif /* HAVE_NTGUI */
4651 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
4652 RGB members are set. F is the frame on which this all happens.
4653 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
4656 x_from_xcolors (struct frame
*f
, struct image
*img
, XColor
*colors
)
4659 XImagePtr oimg
= NULL
;
4662 init_color_table ();
4664 x_clear_image_1 (f
, img
, CLEAR_IMAGE_PIXMAP
| CLEAR_IMAGE_COLORS
);
4665 image_create_x_image_and_pixmap (f
, img
, img
->width
, img
->height
, 0,
4668 for (y
= 0; y
< img
->height
; ++y
)
4669 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4671 unsigned long pixel
;
4672 pixel
= lookup_rgb_color (f
, p
->red
, p
->green
, p
->blue
);
4673 XPutPixel (oimg
, x
, y
, pixel
);
4678 image_put_x_image (f
, img
, oimg
, 0);
4679 #ifdef COLOR_TABLE_SUPPORT
4680 img
->colors
= colors_in_color_table (&img
->ncolors
);
4681 free_color_table ();
4682 #endif /* COLOR_TABLE_SUPPORT */
4686 /* On frame F, perform edge-detection on image IMG.
4688 MATRIX is a nine-element array specifying the transformation
4689 matrix. See emboss_matrix for an example.
4691 COLOR_ADJUST is a color adjustment added to each pixel of the
4695 x_detect_edges (struct frame
*f
, struct image
*img
, int *matrix
, int color_adjust
)
4697 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4701 for (i
= sum
= 0; i
< 9; ++i
)
4702 sum
+= eabs (matrix
[i
]);
4704 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
4706 if (min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *new / img
->width
< img
->height
)
4707 memory_full (SIZE_MAX
);
4708 new = xmalloc (sizeof *new * img
->width
* img
->height
);
4710 for (y
= 0; y
< img
->height
; ++y
)
4712 p
= COLOR (new, 0, y
);
4713 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4714 p
= COLOR (new, img
->width
- 1, y
);
4715 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4718 for (x
= 1; x
< img
->width
- 1; ++x
)
4720 p
= COLOR (new, x
, 0);
4721 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4722 p
= COLOR (new, x
, img
->height
- 1);
4723 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4726 for (y
= 1; y
< img
->height
- 1; ++y
)
4728 p
= COLOR (new, 1, y
);
4730 for (x
= 1; x
< img
->width
- 1; ++x
, ++p
)
4732 int r
, g
, b
, yy
, xx
;
4735 for (yy
= y
- 1; yy
< y
+ 2; ++yy
)
4736 for (xx
= x
- 1; xx
< x
+ 2; ++xx
, ++i
)
4739 XColor
*t
= COLOR (colors
, xx
, yy
);
4740 r
+= matrix
[i
] * t
->red
;
4741 g
+= matrix
[i
] * t
->green
;
4742 b
+= matrix
[i
] * t
->blue
;
4745 r
= (r
/ sum
+ color_adjust
) & 0xffff;
4746 g
= (g
/ sum
+ color_adjust
) & 0xffff;
4747 b
= (b
/ sum
+ color_adjust
) & 0xffff;
4748 p
->red
= p
->green
= p
->blue
= COLOR_INTENSITY (r
, g
, b
);
4753 x_from_xcolors (f
, img
, new);
4759 /* Perform the pre-defined `emboss' edge-detection on image IMG
4763 x_emboss (struct frame
*f
, struct image
*img
)
4765 x_detect_edges (f
, img
, emboss_matrix
, 0xffff / 2);
4769 /* Transform image IMG which is used on frame F with a Laplace
4770 edge-detection algorithm. The result is an image that can be used
4771 to draw disabled buttons, for example. */
4774 x_laplace (struct frame
*f
, struct image
*img
)
4776 x_detect_edges (f
, img
, laplace_matrix
, 45000);
4780 /* Perform edge-detection on image IMG on frame F, with specified
4781 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
4783 MATRIX must be either
4785 - a list of at least 9 numbers in row-major form
4786 - a vector of at least 9 numbers
4788 COLOR_ADJUST nil means use a default; otherwise it must be a
4792 x_edge_detection (struct frame
*f
, struct image
*img
, Lisp_Object matrix
,
4793 Lisp_Object color_adjust
)
4801 i
< 9 && CONSP (matrix
) && NUMBERP (XCAR (matrix
));
4802 ++i
, matrix
= XCDR (matrix
))
4803 trans
[i
] = XFLOATINT (XCAR (matrix
));
4805 else if (VECTORP (matrix
) && ASIZE (matrix
) >= 9)
4807 for (i
= 0; i
< 9 && NUMBERP (AREF (matrix
, i
)); ++i
)
4808 trans
[i
] = XFLOATINT (AREF (matrix
, i
));
4811 if (NILP (color_adjust
))
4812 color_adjust
= make_number (0xffff / 2);
4814 if (i
== 9 && NUMBERP (color_adjust
))
4815 x_detect_edges (f
, img
, trans
, XFLOATINT (color_adjust
));
4819 /* Transform image IMG on frame F so that it looks disabled. */
4822 x_disable_image (struct frame
*f
, struct image
*img
)
4824 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
4826 int n_planes
= dpyinfo
->n_planes
* dpyinfo
->n_cbits
;
4828 int n_planes
= dpyinfo
->n_planes
;
4829 #endif /* HAVE_NTGUI */
4833 /* Color (or grayscale). Convert to gray, and equalize. Just
4834 drawing such images with a stipple can look very odd, so
4835 we're using this method instead. */
4836 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4838 const int h
= 15000;
4839 const int l
= 30000;
4841 for (p
= colors
, end
= colors
+ img
->width
* img
->height
;
4845 int i
= COLOR_INTENSITY (p
->red
, p
->green
, p
->blue
);
4846 int i2
= (0xffff - h
- l
) * i
/ 0xffff + l
;
4847 p
->red
= p
->green
= p
->blue
= i2
;
4850 x_from_xcolors (f
, img
, colors
);
4853 /* Draw a cross over the disabled image, if we must or if we
4855 if (n_planes
< 2 || cross_disabled_images
)
4858 #ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
4860 #define MaskForeground(f) WHITE_PIX_DEFAULT (f)
4862 Display
*dpy
= FRAME_X_DISPLAY (f
);
4865 image_sync_to_pixmaps (f
, img
);
4866 gc
= XCreateGC (dpy
, img
->pixmap
, 0, NULL
);
4867 XSetForeground (dpy
, gc
, BLACK_PIX_DEFAULT (f
));
4868 XDrawLine (dpy
, img
->pixmap
, gc
, 0, 0,
4869 img
->width
- 1, img
->height
- 1);
4870 XDrawLine (dpy
, img
->pixmap
, gc
, 0, img
->height
- 1,
4876 gc
= XCreateGC (dpy
, img
->mask
, 0, NULL
);
4877 XSetForeground (dpy
, gc
, MaskForeground (f
));
4878 XDrawLine (dpy
, img
->mask
, gc
, 0, 0,
4879 img
->width
- 1, img
->height
- 1);
4880 XDrawLine (dpy
, img
->mask
, gc
, 0, img
->height
- 1,
4884 #endif /* !HAVE_NS */
4889 hdc
= get_frame_dc (f
);
4890 bmpdc
= CreateCompatibleDC (hdc
);
4891 release_frame_dc (f
, hdc
);
4893 prev
= SelectObject (bmpdc
, img
->pixmap
);
4895 SetTextColor (bmpdc
, BLACK_PIX_DEFAULT (f
));
4896 MoveToEx (bmpdc
, 0, 0, NULL
);
4897 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
4898 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
4899 LineTo (bmpdc
, img
->width
- 1, 0);
4903 SelectObject (bmpdc
, img
->mask
);
4904 SetTextColor (bmpdc
, WHITE_PIX_DEFAULT (f
));
4905 MoveToEx (bmpdc
, 0, 0, NULL
);
4906 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
4907 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
4908 LineTo (bmpdc
, img
->width
- 1, 0);
4910 SelectObject (bmpdc
, prev
);
4912 #endif /* HAVE_NTGUI */
4917 /* Build a mask for image IMG which is used on frame F. FILE is the
4918 name of an image file, for error messages. HOW determines how to
4919 determine the background color of IMG. If it is a list '(R G B)',
4920 with R, G, and B being integers >= 0, take that as the color of the
4921 background. Otherwise, determine the background color of IMG
4925 x_build_heuristic_mask (struct frame
*f
, struct image
*img
, Lisp_Object how
)
4927 XImagePtr_or_DC ximg
;
4934 #endif /* HAVE_NTGUI */
4936 bool use_img_background
;
4937 unsigned long bg
= 0;
4940 x_clear_image_1 (f
, img
, CLEAR_IMAGE_MASK
);
4944 /* Create an image and pixmap serving as mask. */
4945 if (! image_create_x_image_and_pixmap (f
, img
, img
->width
, img
->height
, 1,
4948 #endif /* !HAVE_NS */
4950 /* Create the bit array serving as mask. */
4951 row_width
= (img
->width
+ 7) / 8;
4952 mask_img
= xzalloc (row_width
* img
->height
);
4953 #endif /* HAVE_NTGUI */
4955 /* Get the X image or create a memory device context for IMG. */
4956 ximg
= image_get_x_image_or_dc (f
, img
, 0, &prev
);
4958 /* Determine the background color of ximg. If HOW is `(R G B)'
4959 take that as color. Otherwise, use the image's background color. */
4960 use_img_background
= 1;
4966 for (i
= 0; i
< 3 && CONSP (how
) && NATNUMP (XCAR (how
)); ++i
)
4968 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
4972 if (i
== 3 && NILP (how
))
4974 char color_name
[30];
4975 sprintf (color_name
, "#%04x%04x%04x", rgb
[0], rgb
[1], rgb
[2]);
4978 0x00ffffff & /* Filter out palette info. */
4979 #endif /* HAVE_NTGUI */
4980 x_alloc_image_color (f
, img
, build_string (color_name
), 0));
4981 use_img_background
= 0;
4985 if (use_img_background
)
4986 bg
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
4988 /* Set all bits in mask_img to 1 whose color in ximg is different
4989 from the background color bg. */
4991 for (y
= 0; y
< img
->height
; ++y
)
4992 for (x
= 0; x
< img
->width
; ++x
)
4994 XPutPixel (mask_img
, x
, y
, (XGetPixel (ximg
, x
, y
) != bg
4995 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
));
4997 if (XGetPixel (ximg
, x
, y
) == bg
)
4998 ns_set_alpha (ximg
, x
, y
, 0);
4999 #endif /* HAVE_NS */
5001 /* Fill in the background_transparent field while we have the mask handy. */
5002 image_background_transparent (img
, f
, mask_img
);
5004 /* Put mask_img into the image. */
5005 image_put_x_image (f
, img
, mask_img
, 1);
5006 #endif /* !HAVE_NS */
5008 for (y
= 0; y
< img
->height
; ++y
)
5009 for (x
= 0; x
< img
->width
; ++x
)
5011 COLORREF p
= GetPixel (ximg
, x
, y
);
5013 mask_img
[y
* row_width
+ x
/ 8] |= 1 << (x
% 8);
5016 /* Create the mask image. */
5017 img
->mask
= w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
,
5019 /* Fill in the background_transparent field while we have the mask handy. */
5020 SelectObject (ximg
, img
->mask
);
5021 image_background_transparent (img
, f
, ximg
);
5023 /* Was: x_destroy_x_image ((XImagePtr )mask_img); which seems bogus ++kfs */
5025 #endif /* HAVE_NTGUI */
5027 image_unget_x_image_or_dc (img
, 0, ximg
, prev
);
5031 /***********************************************************************
5032 PBM (mono, gray, color)
5033 ***********************************************************************/
5035 static bool pbm_image_p (Lisp_Object object
);
5036 static bool pbm_load (struct frame
*f
, struct image
*img
);
5038 /* The symbol `pbm' identifying images of this type. */
5040 static Lisp_Object Qpbm
;
5042 /* Indices of image specification fields in gs_format, below. */
5044 enum pbm_keyword_index
5060 /* Vector of image_keyword structures describing the format
5061 of valid user-defined image specifications. */
5063 static const struct image_keyword pbm_format
[PBM_LAST
] =
5065 {":type", IMAGE_SYMBOL_VALUE
, 1},
5066 {":file", IMAGE_STRING_VALUE
, 0},
5067 {":data", IMAGE_STRING_VALUE
, 0},
5068 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5069 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
5070 {":relief", IMAGE_INTEGER_VALUE
, 0},
5071 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5072 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5073 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5074 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
5075 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
5078 /* Structure describing the image type `pbm'. */
5080 static struct image_type pbm_type
=
5091 /* Return true if OBJECT is a valid PBM image specification. */
5094 pbm_image_p (Lisp_Object object
)
5096 struct image_keyword fmt
[PBM_LAST
];
5098 memcpy (fmt
, pbm_format
, sizeof fmt
);
5100 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
))
5103 /* Must specify either :data or :file. */
5104 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
5108 /* Scan a decimal number from *S and return it. Advance *S while
5109 reading the number. END is the end of the string. Value is -1 at
5113 pbm_scan_number (unsigned char **s
, unsigned char *end
)
5115 int c
= 0, val
= -1;
5119 /* Skip white-space. */
5120 while (*s
< end
&& (c
= *(*s
)++, c_isspace (c
)))
5125 /* Skip comment to end of line. */
5126 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n'))
5129 else if (c_isdigit (c
))
5131 /* Read decimal number. */
5133 while (*s
< end
&& (c
= *(*s
)++, c_isdigit (c
)))
5134 val
= 10 * val
+ c
- '0';
5145 /* Load PBM image IMG for use on frame F. */
5148 pbm_load (struct frame
*f
, struct image
*img
)
5152 int width
, height
, max_color_idx
= 0;
5154 Lisp_Object file
, specified_file
;
5155 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
5156 unsigned char *contents
= NULL
;
5157 unsigned char *end
, *p
;
5160 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5162 if (STRINGP (specified_file
))
5164 file
= x_find_image_file (specified_file
);
5165 if (!STRINGP (file
))
5167 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5171 contents
= slurp_file (SSDATA (file
), &size
);
5172 if (contents
== NULL
)
5174 image_error ("Error reading `%s'", file
, Qnil
);
5179 end
= contents
+ size
;
5184 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5185 if (!STRINGP (data
))
5187 image_error ("Invalid image data `%s'", data
, Qnil
);
5191 end
= p
+ SBYTES (data
);
5194 /* Check magic number. */
5195 if (end
- p
< 2 || *p
++ != 'P')
5197 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5206 raw_p
= 0, type
= PBM_MONO
;
5210 raw_p
= 0, type
= PBM_GRAY
;
5214 raw_p
= 0, type
= PBM_COLOR
;
5218 raw_p
= 1, type
= PBM_MONO
;
5222 raw_p
= 1, type
= PBM_GRAY
;
5226 raw_p
= 1, type
= PBM_COLOR
;
5230 image_error ("Not a PBM image: `%s'", img
->spec
, Qnil
);
5234 /* Read width, height, maximum color-component. Characters
5235 starting with `#' up to the end of a line are ignored. */
5236 width
= pbm_scan_number (&p
, end
);
5237 height
= pbm_scan_number (&p
, end
);
5239 if (type
!= PBM_MONO
)
5241 max_color_idx
= pbm_scan_number (&p
, end
);
5242 if (max_color_idx
> 65535 || max_color_idx
< 0)
5244 image_error ("Unsupported maximum PBM color value", Qnil
, Qnil
);
5249 if (!check_image_size (f
, width
, height
))
5251 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
5255 if (!image_create_x_image_and_pixmap (f
, img
, width
, height
, 0, &ximg
, 0))
5258 /* Initialize the color hash table. */
5259 init_color_table ();
5261 if (type
== PBM_MONO
)
5264 struct image_keyword fmt
[PBM_LAST
];
5265 unsigned long fg
= FRAME_FOREGROUND_PIXEL (f
);
5266 unsigned long bg
= FRAME_BACKGROUND_PIXEL (f
);
5268 /* Parse the image specification. */
5269 memcpy (fmt
, pbm_format
, sizeof fmt
);
5270 parse_image_spec (img
->spec
, fmt
, PBM_LAST
, Qpbm
);
5272 /* Get foreground and background colors, maybe allocate colors. */
5273 if (fmt
[PBM_FOREGROUND
].count
5274 && STRINGP (fmt
[PBM_FOREGROUND
].value
))
5275 fg
= x_alloc_image_color (f
, img
, fmt
[PBM_FOREGROUND
].value
, fg
);
5276 if (fmt
[PBM_BACKGROUND
].count
5277 && STRINGP (fmt
[PBM_BACKGROUND
].value
))
5279 bg
= x_alloc_image_color (f
, img
, fmt
[PBM_BACKGROUND
].value
, bg
);
5280 img
->background
= bg
;
5281 img
->background_valid
= 1;
5284 for (y
= 0; y
< height
; ++y
)
5285 for (x
= 0; x
< width
; ++x
)
5293 x_destroy_x_image (ximg
);
5294 x_clear_image (f
, img
);
5295 image_error ("Invalid image size in image `%s'",
5305 g
= pbm_scan_number (&p
, end
);
5307 XPutPixel (ximg
, x
, y
, g
? fg
: bg
);
5312 int expected_size
= height
* width
;
5313 if (max_color_idx
> 255)
5315 if (type
== PBM_COLOR
)
5318 if (raw_p
&& p
+ expected_size
> end
)
5320 x_destroy_x_image (ximg
);
5321 x_clear_image (f
, img
);
5322 image_error ("Invalid image size in image `%s'",
5327 for (y
= 0; y
< height
; ++y
)
5328 for (x
= 0; x
< width
; ++x
)
5332 if (type
== PBM_GRAY
&& raw_p
)
5335 if (max_color_idx
> 255)
5336 r
= g
= b
= r
* 256 + *p
++;
5338 else if (type
== PBM_GRAY
)
5339 r
= g
= b
= pbm_scan_number (&p
, end
);
5343 if (max_color_idx
> 255)
5346 if (max_color_idx
> 255)
5349 if (max_color_idx
> 255)
5354 r
= pbm_scan_number (&p
, end
);
5355 g
= pbm_scan_number (&p
, end
);
5356 b
= pbm_scan_number (&p
, end
);
5359 if (r
< 0 || g
< 0 || b
< 0)
5361 x_destroy_x_image (ximg
);
5362 image_error ("Invalid pixel value in image `%s'",
5367 /* RGB values are now in the range 0..max_color_idx.
5368 Scale this to the range 0..0xffff supported by X. */
5369 r
= (double) r
* 65535 / max_color_idx
;
5370 g
= (double) g
* 65535 / max_color_idx
;
5371 b
= (double) b
* 65535 / max_color_idx
;
5372 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
5376 #ifdef COLOR_TABLE_SUPPORT
5377 /* Store in IMG->colors the colors allocated for the image, and
5378 free the color table. */
5379 img
->colors
= colors_in_color_table (&img
->ncolors
);
5380 free_color_table ();
5381 #endif /* COLOR_TABLE_SUPPORT */
5384 img
->height
= height
;
5386 /* Maybe fill in the background field while we have ximg handy. */
5388 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
5389 /* Casting avoids a GCC warning. */
5390 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
5392 /* Put ximg into the image. */
5393 image_put_x_image (f
, img
, ximg
, 0);
5395 /* X and W32 versions did it here, MAC version above. ++kfs
5397 img->height = height; */
5404 /***********************************************************************
5406 ***********************************************************************/
5408 #if defined (HAVE_PNG) || defined (HAVE_NS)
5410 /* Function prototypes. */
5412 static bool png_image_p (Lisp_Object object
);
5413 static bool png_load (struct frame
*f
, struct image
*img
);
5415 /* The symbol `png' identifying images of this type. */
5417 static Lisp_Object Qpng
;
5419 /* Indices of image specification fields in png_format, below. */
5421 enum png_keyword_index
5436 /* Vector of image_keyword structures describing the format
5437 of valid user-defined image specifications. */
5439 static const struct image_keyword png_format
[PNG_LAST
] =
5441 {":type", IMAGE_SYMBOL_VALUE
, 1},
5442 {":data", IMAGE_STRING_VALUE
, 0},
5443 {":file", IMAGE_STRING_VALUE
, 0},
5444 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5445 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
5446 {":relief", IMAGE_INTEGER_VALUE
, 0},
5447 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5448 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5449 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5450 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
5453 #if defined HAVE_NTGUI && defined WINDOWSNT
5454 static bool init_png_functions (void);
5456 #define init_png_functions NULL
5459 /* Structure describing the image type `png'. */
5461 static struct image_type png_type
=
5471 /* Return true if OBJECT is a valid PNG image specification. */
5474 png_image_p (Lisp_Object object
)
5476 struct image_keyword fmt
[PNG_LAST
];
5477 memcpy (fmt
, png_format
, sizeof fmt
);
5479 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
5482 /* Must specify either the :data or :file keyword. */
5483 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
5486 #endif /* HAVE_PNG || HAVE_NS */
5492 /* PNG library details. */
5494 DEF_IMGLIB_FN (png_voidp
, png_get_io_ptr
, (png_structp
));
5495 DEF_IMGLIB_FN (int, png_sig_cmp
, (png_bytep
, png_size_t
, png_size_t
));
5496 DEF_IMGLIB_FN (png_structp
, png_create_read_struct
, (png_const_charp
, png_voidp
,
5497 png_error_ptr
, png_error_ptr
));
5498 DEF_IMGLIB_FN (png_infop
, png_create_info_struct
, (png_structp
));
5499 DEF_IMGLIB_FN (void, png_destroy_read_struct
, (png_structpp
, png_infopp
, png_infopp
));
5500 DEF_IMGLIB_FN (void, png_set_read_fn
, (png_structp
, png_voidp
, png_rw_ptr
));
5501 DEF_IMGLIB_FN (void, png_set_sig_bytes
, (png_structp
, int));
5502 DEF_IMGLIB_FN (void, png_read_info
, (png_structp
, png_infop
));
5503 DEF_IMGLIB_FN (png_uint_32
, png_get_IHDR
, (png_structp
, png_infop
,
5504 png_uint_32
*, png_uint_32
*,
5505 int *, int *, int *, int *, int *));
5506 DEF_IMGLIB_FN (png_uint_32
, png_get_valid
, (png_structp
, png_infop
, png_uint_32
));
5507 DEF_IMGLIB_FN (void, png_set_strip_16
, (png_structp
));
5508 DEF_IMGLIB_FN (void, png_set_expand
, (png_structp
));
5509 DEF_IMGLIB_FN (void, png_set_gray_to_rgb
, (png_structp
));
5510 DEF_IMGLIB_FN (void, png_set_background
, (png_structp
, png_color_16p
,
5512 DEF_IMGLIB_FN (png_uint_32
, png_get_bKGD
, (png_structp
, png_infop
, png_color_16p
*));
5513 DEF_IMGLIB_FN (void, png_read_update_info
, (png_structp
, png_infop
));
5514 DEF_IMGLIB_FN (png_byte
, png_get_channels
, (png_structp
, png_infop
));
5515 DEF_IMGLIB_FN (png_size_t
, png_get_rowbytes
, (png_structp
, png_infop
));
5516 DEF_IMGLIB_FN (void, png_read_image
, (png_structp
, png_bytepp
));
5517 DEF_IMGLIB_FN (void, png_read_end
, (png_structp
, png_infop
));
5518 DEF_IMGLIB_FN (void, png_error
, (png_structp
, png_const_charp
));
5520 #if (PNG_LIBPNG_VER >= 10500)
5521 DEF_IMGLIB_FN (void, png_longjmp
, (png_structp
, int));
5522 DEF_IMGLIB_FN (jmp_buf *, png_set_longjmp_fn
, (png_structp
, png_longjmp_ptr
, size_t));
5523 #endif /* libpng version >= 1.5 */
5526 init_png_functions (void)
5530 if (!(library
= w32_delayed_load (Qpng
)))
5533 LOAD_IMGLIB_FN (library
, png_get_io_ptr
);
5534 LOAD_IMGLIB_FN (library
, png_sig_cmp
);
5535 LOAD_IMGLIB_FN (library
, png_create_read_struct
);
5536 LOAD_IMGLIB_FN (library
, png_create_info_struct
);
5537 LOAD_IMGLIB_FN (library
, png_destroy_read_struct
);
5538 LOAD_IMGLIB_FN (library
, png_set_read_fn
);
5539 LOAD_IMGLIB_FN (library
, png_set_sig_bytes
);
5540 LOAD_IMGLIB_FN (library
, png_read_info
);
5541 LOAD_IMGLIB_FN (library
, png_get_IHDR
);
5542 LOAD_IMGLIB_FN (library
, png_get_valid
);
5543 LOAD_IMGLIB_FN (library
, png_set_strip_16
);
5544 LOAD_IMGLIB_FN (library
, png_set_expand
);
5545 LOAD_IMGLIB_FN (library
, png_set_gray_to_rgb
);
5546 LOAD_IMGLIB_FN (library
, png_set_background
);
5547 LOAD_IMGLIB_FN (library
, png_get_bKGD
);
5548 LOAD_IMGLIB_FN (library
, png_read_update_info
);
5549 LOAD_IMGLIB_FN (library
, png_get_channels
);
5550 LOAD_IMGLIB_FN (library
, png_get_rowbytes
);
5551 LOAD_IMGLIB_FN (library
, png_read_image
);
5552 LOAD_IMGLIB_FN (library
, png_read_end
);
5553 LOAD_IMGLIB_FN (library
, png_error
);
5555 #if (PNG_LIBPNG_VER >= 10500)
5556 LOAD_IMGLIB_FN (library
, png_longjmp
);
5557 LOAD_IMGLIB_FN (library
, png_set_longjmp_fn
);
5558 #endif /* libpng version >= 1.5 */
5564 #define fn_png_get_io_ptr png_get_io_ptr
5565 #define fn_png_sig_cmp png_sig_cmp
5566 #define fn_png_create_read_struct png_create_read_struct
5567 #define fn_png_create_info_struct png_create_info_struct
5568 #define fn_png_destroy_read_struct png_destroy_read_struct
5569 #define fn_png_set_read_fn png_set_read_fn
5570 #define fn_png_set_sig_bytes png_set_sig_bytes
5571 #define fn_png_read_info png_read_info
5572 #define fn_png_get_IHDR png_get_IHDR
5573 #define fn_png_get_valid png_get_valid
5574 #define fn_png_set_strip_16 png_set_strip_16
5575 #define fn_png_set_expand png_set_expand
5576 #define fn_png_set_gray_to_rgb png_set_gray_to_rgb
5577 #define fn_png_set_background png_set_background
5578 #define fn_png_get_bKGD png_get_bKGD
5579 #define fn_png_read_update_info png_read_update_info
5580 #define fn_png_get_channels png_get_channels
5581 #define fn_png_get_rowbytes png_get_rowbytes
5582 #define fn_png_read_image png_read_image
5583 #define fn_png_read_end png_read_end
5584 #define fn_png_error png_error
5586 #if (PNG_LIBPNG_VER >= 10500)
5587 #define fn_png_longjmp png_longjmp
5588 #define fn_png_set_longjmp_fn png_set_longjmp_fn
5589 #endif /* libpng version >= 1.5 */
5591 #endif /* WINDOWSNT */
5593 /* Possibly inefficient/inexact substitutes for _setjmp and _longjmp.
5594 Do not use sys_setjmp, as PNG supports only jmp_buf. The _longjmp
5595 substitute may munge the signal mask, but that should be OK here.
5596 MinGW (MS-Windows) uses _setjmp and defines setjmp to _setjmp in
5597 the system header setjmp.h; don't mess up that. */
5598 #ifndef HAVE__SETJMP
5599 # define _setjmp(j) setjmp (j)
5600 # define _longjmp longjmp
5603 #if (PNG_LIBPNG_VER < 10500)
5604 #define PNG_LONGJMP(ptr) (_longjmp ((ptr)->jmpbuf, 1))
5605 #define PNG_JMPBUF(ptr) ((ptr)->jmpbuf)
5607 /* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908) */
5608 #define PNG_LONGJMP(ptr) (fn_png_longjmp ((ptr), 1))
5609 #define PNG_JMPBUF(ptr) \
5610 (*fn_png_set_longjmp_fn ((ptr), _longjmp, sizeof (jmp_buf)))
5613 /* Error and warning handlers installed when the PNG library
5616 static _Noreturn
void
5617 my_png_error (png_struct
*png_ptr
, const char *msg
)
5619 eassert (png_ptr
!= NULL
);
5620 /* Avoid compiler warning about deprecated direct access to
5621 png_ptr's fields in libpng versions 1.4.x. */
5622 image_error ("PNG error: %s", build_string (msg
), Qnil
);
5623 PNG_LONGJMP (png_ptr
);
5628 my_png_warning (png_struct
*png_ptr
, const char *msg
)
5630 eassert (png_ptr
!= NULL
);
5631 image_error ("PNG warning: %s", build_string (msg
), Qnil
);
5634 /* Memory source for PNG decoding. */
5636 struct png_memory_storage
5638 unsigned char *bytes
; /* The data */
5639 ptrdiff_t len
; /* How big is it? */
5640 ptrdiff_t index
; /* Where are we? */
5644 /* Function set as reader function when reading PNG image from memory.
5645 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5646 bytes from the input to DATA. */
5649 png_read_from_memory (png_structp png_ptr
, png_bytep data
, png_size_t length
)
5651 struct png_memory_storage
*tbr
= fn_png_get_io_ptr (png_ptr
);
5653 if (length
> tbr
->len
- tbr
->index
)
5654 fn_png_error (png_ptr
, "Read error");
5656 memcpy (data
, tbr
->bytes
+ tbr
->index
, length
);
5657 tbr
->index
= tbr
->index
+ length
;
5661 /* Function set as reader function when reading PNG image from a file.
5662 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5663 bytes from the input to DATA. */
5666 png_read_from_file (png_structp png_ptr
, png_bytep data
, png_size_t length
)
5668 FILE *fp
= fn_png_get_io_ptr (png_ptr
);
5670 if (fread (data
, 1, length
, fp
) < length
)
5671 fn_png_error (png_ptr
, "Read error");
5675 /* Load PNG image IMG for use on frame F. Value is true if
5678 struct png_load_context
5680 /* These are members so that longjmp doesn't munge local variables. */
5681 png_struct
*png_ptr
;
5690 png_load_body (struct frame
*f
, struct image
*img
, struct png_load_context
*c
)
5692 Lisp_Object file
, specified_file
;
5693 Lisp_Object specified_data
;
5696 XImagePtr ximg
, mask_img
= NULL
;
5697 png_struct
*png_ptr
;
5698 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
5701 png_byte
*pixels
= NULL
;
5702 png_byte
**rows
= NULL
;
5703 png_uint_32 width
, height
;
5704 int bit_depth
, color_type
, interlace_type
;
5706 png_uint_32 row_bytes
;
5708 struct png_memory_storage tbr
; /* Data to be read */
5710 /* Find out what file to load. */
5711 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5712 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5714 if (NILP (specified_data
))
5716 file
= x_find_image_file (specified_file
);
5717 if (!STRINGP (file
))
5719 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
5723 /* Open the image file. */
5724 fp
= emacs_fopen (SSDATA (file
), "rb");
5727 image_error ("Cannot open image file `%s'", file
, Qnil
);
5731 /* Check PNG signature. */
5732 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
5733 || fn_png_sig_cmp (sig
, 0, sizeof sig
))
5736 image_error ("Not a PNG file: `%s'", file
, Qnil
);
5742 if (!STRINGP (specified_data
))
5744 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
5748 /* Read from memory. */
5749 tbr
.bytes
= SDATA (specified_data
);
5750 tbr
.len
= SBYTES (specified_data
);
5753 /* Check PNG signature. */
5754 if (tbr
.len
< sizeof sig
5755 || fn_png_sig_cmp (tbr
.bytes
, 0, sizeof sig
))
5757 image_error ("Not a PNG image: `%s'", img
->spec
, Qnil
);
5761 /* Need to skip past the signature. */
5762 tbr
.bytes
+= sizeof (sig
);
5765 /* Initialize read and info structs for PNG lib. */
5766 png_ptr
= fn_png_create_read_struct (PNG_LIBPNG_VER_STRING
,
5771 info_ptr
= fn_png_create_info_struct (png_ptr
);
5772 end_info
= fn_png_create_info_struct (png_ptr
);
5775 c
->png_ptr
= png_ptr
;
5776 c
->info_ptr
= info_ptr
;
5777 c
->end_info
= end_info
;
5782 if (! (info_ptr
&& end_info
))
5784 fn_png_destroy_read_struct (&c
->png_ptr
, &c
->info_ptr
, &c
->end_info
);
5789 if (fp
) fclose (fp
);
5793 /* Set error jump-back. We come back here when the PNG library
5794 detects an error. */
5795 if (_setjmp (PNG_JMPBUF (png_ptr
)))
5799 fn_png_destroy_read_struct (&c
->png_ptr
, &c
->info_ptr
, &c
->end_info
);
5807 /* Silence a bogus diagnostic; see GCC bug 54561. */
5808 IF_LINT (fp
= c
->fp
);
5810 /* Read image info. */
5811 if (!NILP (specified_data
))
5812 fn_png_set_read_fn (png_ptr
, &tbr
, png_read_from_memory
);
5814 fn_png_set_read_fn (png_ptr
, fp
, png_read_from_file
);
5816 fn_png_set_sig_bytes (png_ptr
, sizeof sig
);
5817 fn_png_read_info (png_ptr
, info_ptr
);
5818 fn_png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
5819 &interlace_type
, NULL
, NULL
);
5821 if (! (width
<= INT_MAX
&& height
<= INT_MAX
5822 && check_image_size (f
, width
, height
)))
5824 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
5828 /* Create the X image and pixmap now, so that the work below can be
5829 omitted if the image is too large for X. */
5830 if (!image_create_x_image_and_pixmap (f
, img
, width
, height
, 0, &ximg
, 0))
5833 /* If image contains simply transparency data, we prefer to
5834 construct a clipping mask. */
5835 if (fn_png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
5840 /* This function is easier to write if we only have to handle
5841 one data format: RGB or RGBA with 8 bits per channel. Let's
5842 transform other formats into that format. */
5844 /* Strip more than 8 bits per channel. */
5845 if (bit_depth
== 16)
5846 fn_png_set_strip_16 (png_ptr
);
5848 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
5850 fn_png_set_expand (png_ptr
);
5852 /* Convert grayscale images to RGB. */
5853 if (color_type
== PNG_COLOR_TYPE_GRAY
5854 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
5855 fn_png_set_gray_to_rgb (png_ptr
);
5857 /* Handle alpha channel by combining the image with a background
5858 color. Do this only if a real alpha channel is supplied. For
5859 simple transparency, we prefer a clipping mask. */
5862 /* png_color_16 *image_bg; */
5863 Lisp_Object specified_bg
5864 = image_spec_value (img
->spec
, QCbackground
, NULL
);
5865 int shift
= (bit_depth
== 16) ? 0 : 8;
5867 if (STRINGP (specified_bg
))
5868 /* The user specified `:background', use that. */
5871 if (x_defined_color (f
, SSDATA (specified_bg
), &color
, 0))
5873 png_color_16 user_bg
;
5875 memset (&user_bg
, 0, sizeof user_bg
);
5876 user_bg
.red
= color
.red
>> shift
;
5877 user_bg
.green
= color
.green
>> shift
;
5878 user_bg
.blue
= color
.blue
>> shift
;
5880 fn_png_set_background (png_ptr
, &user_bg
,
5881 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
5886 /* We use the current frame background, ignoring any default
5887 background color set by the image. */
5888 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
5890 png_color_16 frame_background
;
5892 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
5893 x_query_color (f
, &color
);
5895 memset (&frame_background
, 0, sizeof frame_background
);
5896 frame_background
.red
= color
.red
>> shift
;
5897 frame_background
.green
= color
.green
>> shift
;
5898 frame_background
.blue
= color
.blue
>> shift
;
5899 #endif /* HAVE_X_WINDOWS */
5901 fn_png_set_background (png_ptr
, &frame_background
,
5902 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
5906 /* Update info structure. */
5907 fn_png_read_update_info (png_ptr
, info_ptr
);
5909 /* Get number of channels. Valid values are 1 for grayscale images
5910 and images with a palette, 2 for grayscale images with transparency
5911 information (alpha channel), 3 for RGB images, and 4 for RGB
5912 images with alpha channel, i.e. RGBA. If conversions above were
5913 sufficient we should only have 3 or 4 channels here. */
5914 channels
= fn_png_get_channels (png_ptr
, info_ptr
);
5915 eassert (channels
== 3 || channels
== 4);
5917 /* Number of bytes needed for one row of the image. */
5918 row_bytes
= fn_png_get_rowbytes (png_ptr
, info_ptr
);
5920 /* Allocate memory for the image. */
5921 if (min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *rows
< height
5922 || min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *pixels
/ height
< row_bytes
)
5923 memory_full (SIZE_MAX
);
5924 c
->pixels
= pixels
= xmalloc (sizeof *pixels
* row_bytes
* height
);
5925 c
->rows
= rows
= xmalloc (height
* sizeof *rows
);
5926 for (i
= 0; i
< height
; ++i
)
5927 rows
[i
] = pixels
+ i
* row_bytes
;
5929 /* Read the entire image. */
5930 fn_png_read_image (png_ptr
, rows
);
5931 fn_png_read_end (png_ptr
, info_ptr
);
5938 /* Create an image and pixmap serving as mask if the PNG image
5939 contains an alpha channel. */
5942 && !image_create_x_image_and_pixmap (f
, img
, width
, height
, 1,
5945 x_destroy_x_image (ximg
);
5946 x_clear_image_1 (f
, img
, CLEAR_IMAGE_PIXMAP
);
5950 /* Fill the X image and mask from PNG data. */
5951 init_color_table ();
5953 for (y
= 0; y
< height
; ++y
)
5955 png_byte
*p
= rows
[y
];
5957 for (x
= 0; x
< width
; ++x
)
5964 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
5965 /* An alpha channel, aka mask channel, associates variable
5966 transparency with an image. Where other image formats
5967 support binary transparency---fully transparent or fully
5968 opaque---PNG allows up to 254 levels of partial transparency.
5969 The PNG library implements partial transparency by combining
5970 the image with a specified background color.
5972 I'm not sure how to handle this here nicely: because the
5973 background on which the image is displayed may change, for
5974 real alpha channel support, it would be necessary to create
5975 a new image for each possible background.
5977 What I'm doing now is that a mask is created if we have
5978 boolean transparency information. Otherwise I'm using
5979 the frame's background color to combine the image with. */
5984 XPutPixel (mask_img
, x
, y
, *p
> 0 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
);
5990 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
5991 /* Set IMG's background color from the PNG image, unless the user
5995 if (fn_png_get_bKGD (png_ptr
, info_ptr
, &bg
))
5997 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
5998 img
->background_valid
= 1;
6002 #ifdef COLOR_TABLE_SUPPORT
6003 /* Remember colors allocated for this image. */
6004 img
->colors
= colors_in_color_table (&img
->ncolors
);
6005 free_color_table ();
6006 #endif /* COLOR_TABLE_SUPPORT */
6009 fn_png_destroy_read_struct (&c
->png_ptr
, &c
->info_ptr
, &c
->end_info
);
6014 img
->height
= height
;
6016 /* Maybe fill in the background field while we have ximg handy.
6017 Casting avoids a GCC warning. */
6018 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6020 /* Put ximg into the image. */
6021 image_put_x_image (f
, img
, ximg
, 0);
6023 /* Same for the mask. */
6026 /* Fill in the background_transparent field while we have the
6027 mask handy. Casting avoids a GCC warning. */
6028 image_background_transparent (img
, f
, (XImagePtr_or_DC
)mask_img
);
6030 image_put_x_image (f
, img
, mask_img
, 1);
6037 png_load (struct frame
*f
, struct image
*img
)
6039 struct png_load_context c
;
6040 return png_load_body (f
, img
, &c
);
6043 #else /* HAVE_PNG */
6047 png_load (struct frame
*f
, struct image
*img
)
6049 return ns_load_image (f
, img
,
6050 image_spec_value (img
->spec
, QCfile
, NULL
),
6051 image_spec_value (img
->spec
, QCdata
, NULL
));
6053 #endif /* HAVE_NS */
6056 #endif /* !HAVE_PNG */
6060 /***********************************************************************
6062 ***********************************************************************/
6064 #if defined (HAVE_JPEG) || defined (HAVE_NS)
6066 static bool jpeg_image_p (Lisp_Object object
);
6067 static bool jpeg_load (struct frame
*f
, struct image
*img
);
6069 /* The symbol `jpeg' identifying images of this type. */
6071 static Lisp_Object Qjpeg
;
6073 /* Indices of image specification fields in gs_format, below. */
6075 enum jpeg_keyword_index
6084 JPEG_HEURISTIC_MASK
,
6090 /* Vector of image_keyword structures describing the format
6091 of valid user-defined image specifications. */
6093 static const struct image_keyword jpeg_format
[JPEG_LAST
] =
6095 {":type", IMAGE_SYMBOL_VALUE
, 1},
6096 {":data", IMAGE_STRING_VALUE
, 0},
6097 {":file", IMAGE_STRING_VALUE
, 0},
6098 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6099 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
6100 {":relief", IMAGE_INTEGER_VALUE
, 0},
6101 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6102 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6103 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6104 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
6107 #if defined HAVE_NTGUI && defined WINDOWSNT
6108 static bool init_jpeg_functions (void);
6110 #define init_jpeg_functions NULL
6113 /* Structure describing the image type `jpeg'. */
6115 static struct image_type jpeg_type
=
6121 init_jpeg_functions
,
6125 /* Return true if OBJECT is a valid JPEG image specification. */
6128 jpeg_image_p (Lisp_Object object
)
6130 struct image_keyword fmt
[JPEG_LAST
];
6132 memcpy (fmt
, jpeg_format
, sizeof fmt
);
6134 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
6137 /* Must specify either the :data or :file keyword. */
6138 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
6141 #endif /* HAVE_JPEG || HAVE_NS */
6145 /* Work around a warning about HAVE_STDLIB_H being redefined in
6147 #ifdef HAVE_STDLIB_H
6148 #undef HAVE_STDLIB_H
6149 #endif /* HAVE_STLIB_H */
6151 #if defined (HAVE_NTGUI) && !defined (__WIN32__)
6152 /* In older releases of the jpeg library, jpeglib.h will define boolean
6153 differently depending on __WIN32__, so make sure it is defined. */
6157 /* rpcndr.h (via windows.h) and jpeglib.h both define boolean types.
6158 Some versions of jpeglib try to detect whether rpcndr.h is loaded,
6159 using the Windows boolean type instead of the jpeglib boolean type
6160 if so. Cygwin jpeglib, however, doesn't try to detect whether its
6161 headers are included along with windows.h, so under Cygwin, jpeglib
6162 attempts to define a conflicting boolean type. Worse, forcing
6163 Cygwin jpeglib headers to use the Windows boolean type doesn't work
6164 because it created an ABI incompatibility between the
6165 already-compiled jpeg library and the header interface definition.
6167 The best we can do is to define jpeglib's boolean type to a
6168 different name. This name, jpeg_boolean, remains in effect through
6169 the rest of image.c.
6171 #if defined CYGWIN && defined HAVE_NTGUI
6172 #define boolean jpeg_boolean
6174 #include <jpeglib.h>
6179 /* JPEG library details. */
6180 DEF_IMGLIB_FN (void, jpeg_CreateDecompress
, (j_decompress_ptr
, int, size_t));
6181 DEF_IMGLIB_FN (boolean
, jpeg_start_decompress
, (j_decompress_ptr
));
6182 DEF_IMGLIB_FN (boolean
, jpeg_finish_decompress
, (j_decompress_ptr
));
6183 DEF_IMGLIB_FN (void, jpeg_destroy_decompress
, (j_decompress_ptr
));
6184 DEF_IMGLIB_FN (int, jpeg_read_header
, (j_decompress_ptr
, boolean
));
6185 DEF_IMGLIB_FN (JDIMENSION
, jpeg_read_scanlines
, (j_decompress_ptr
, JSAMPARRAY
, JDIMENSION
));
6186 DEF_IMGLIB_FN (struct jpeg_error_mgr
*, jpeg_std_error
, (struct jpeg_error_mgr
*));
6187 DEF_IMGLIB_FN (boolean
, jpeg_resync_to_restart
, (j_decompress_ptr
, int));
6190 init_jpeg_functions (void)
6194 if (!(library
= w32_delayed_load (Qjpeg
)))
6197 LOAD_IMGLIB_FN (library
, jpeg_finish_decompress
);
6198 LOAD_IMGLIB_FN (library
, jpeg_read_scanlines
);
6199 LOAD_IMGLIB_FN (library
, jpeg_start_decompress
);
6200 LOAD_IMGLIB_FN (library
, jpeg_read_header
);
6201 LOAD_IMGLIB_FN (library
, jpeg_CreateDecompress
);
6202 LOAD_IMGLIB_FN (library
, jpeg_destroy_decompress
);
6203 LOAD_IMGLIB_FN (library
, jpeg_std_error
);
6204 LOAD_IMGLIB_FN (library
, jpeg_resync_to_restart
);
6208 /* Wrapper since we can't directly assign the function pointer
6209 to another function pointer that was declared more completely easily. */
6211 jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo
, int desired
)
6213 return fn_jpeg_resync_to_restart (cinfo
, desired
);
6218 #define fn_jpeg_CreateDecompress(a,b,c) jpeg_create_decompress (a)
6219 #define fn_jpeg_start_decompress jpeg_start_decompress
6220 #define fn_jpeg_finish_decompress jpeg_finish_decompress
6221 #define fn_jpeg_destroy_decompress jpeg_destroy_decompress
6222 #define fn_jpeg_read_header jpeg_read_header
6223 #define fn_jpeg_read_scanlines jpeg_read_scanlines
6224 #define fn_jpeg_std_error jpeg_std_error
6225 #define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart
6227 #endif /* WINDOWSNT */
6229 struct my_jpeg_error_mgr
6231 struct jpeg_error_mgr pub
;
6232 sys_jmp_buf setjmp_buffer
;
6234 /* The remaining members are so that longjmp doesn't munge local
6236 struct jpeg_decompress_struct cinfo
;
6240 MY_JPEG_INVALID_IMAGE_SIZE
,
6241 MY_JPEG_CANNOT_CREATE_X
6249 static _Noreturn
void
6250 my_error_exit (j_common_ptr cinfo
)
6252 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
6253 mgr
->failure_code
= MY_JPEG_ERROR_EXIT
;
6254 sys_longjmp (mgr
->setjmp_buffer
, 1);
6258 /* Init source method for JPEG data source manager. Called by
6259 jpeg_read_header() before any data is actually read. See
6260 libjpeg.doc from the JPEG lib distribution. */
6263 our_common_init_source (j_decompress_ptr cinfo
)
6268 /* Method to terminate data source. Called by
6269 jpeg_finish_decompress() after all data has been processed. */
6272 our_common_term_source (j_decompress_ptr cinfo
)
6277 /* Fill input buffer method for JPEG data source manager. Called
6278 whenever more data is needed. We read the whole image in one step,
6279 so this only adds a fake end of input marker at the end. */
6281 static JOCTET our_memory_buffer
[2];
6284 our_memory_fill_input_buffer (j_decompress_ptr cinfo
)
6286 /* Insert a fake EOI marker. */
6287 struct jpeg_source_mgr
*src
= cinfo
->src
;
6289 our_memory_buffer
[0] = (JOCTET
) 0xFF;
6290 our_memory_buffer
[1] = (JOCTET
) JPEG_EOI
;
6292 src
->next_input_byte
= our_memory_buffer
;
6293 src
->bytes_in_buffer
= 2;
6298 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6299 is the JPEG data source manager. */
6302 our_memory_skip_input_data (j_decompress_ptr cinfo
, long int num_bytes
)
6304 struct jpeg_source_mgr
*src
= cinfo
->src
;
6308 if (num_bytes
> src
->bytes_in_buffer
)
6309 ERREXIT (cinfo
, JERR_INPUT_EOF
);
6311 src
->bytes_in_buffer
-= num_bytes
;
6312 src
->next_input_byte
+= num_bytes
;
6317 /* Set up the JPEG lib for reading an image from DATA which contains
6318 LEN bytes. CINFO is the decompression info structure created for
6319 reading the image. */
6322 jpeg_memory_src (j_decompress_ptr cinfo
, JOCTET
*data
, ptrdiff_t len
)
6324 struct jpeg_source_mgr
*src
= cinfo
->src
;
6328 /* First time for this JPEG object? */
6329 src
= cinfo
->mem
->alloc_small ((j_common_ptr
) cinfo
,
6330 JPOOL_PERMANENT
, sizeof *src
);
6332 src
->next_input_byte
= data
;
6335 src
->init_source
= our_common_init_source
;
6336 src
->fill_input_buffer
= our_memory_fill_input_buffer
;
6337 src
->skip_input_data
= our_memory_skip_input_data
;
6338 src
->resync_to_restart
= jpeg_resync_to_restart_wrapper
; /* Use default method. */
6339 src
->term_source
= our_common_term_source
;
6340 src
->bytes_in_buffer
= len
;
6341 src
->next_input_byte
= data
;
6345 struct jpeg_stdio_mgr
6347 struct jpeg_source_mgr mgr
;
6354 /* Size of buffer to read JPEG from file.
6355 Not too big, as we want to use alloc_small. */
6356 #define JPEG_STDIO_BUFFER_SIZE 8192
6359 /* Fill input buffer method for JPEG data source manager. Called
6360 whenever more data is needed. The data is read from a FILE *. */
6363 our_stdio_fill_input_buffer (j_decompress_ptr cinfo
)
6365 struct jpeg_stdio_mgr
*src
;
6367 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6372 bytes
= fread (src
->buffer
, 1, JPEG_STDIO_BUFFER_SIZE
, src
->file
);
6374 src
->mgr
.bytes_in_buffer
= bytes
;
6377 WARNMS (cinfo
, JWRN_JPEG_EOF
);
6379 src
->buffer
[0] = (JOCTET
) 0xFF;
6380 src
->buffer
[1] = (JOCTET
) JPEG_EOI
;
6381 src
->mgr
.bytes_in_buffer
= 2;
6383 src
->mgr
.next_input_byte
= src
->buffer
;
6390 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6391 is the JPEG data source manager. */
6394 our_stdio_skip_input_data (j_decompress_ptr cinfo
, long int num_bytes
)
6396 struct jpeg_stdio_mgr
*src
;
6397 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6399 while (num_bytes
> 0 && !src
->finished
)
6401 if (num_bytes
<= src
->mgr
.bytes_in_buffer
)
6403 src
->mgr
.bytes_in_buffer
-= num_bytes
;
6404 src
->mgr
.next_input_byte
+= num_bytes
;
6409 num_bytes
-= src
->mgr
.bytes_in_buffer
;
6410 src
->mgr
.bytes_in_buffer
= 0;
6411 src
->mgr
.next_input_byte
= NULL
;
6413 our_stdio_fill_input_buffer (cinfo
);
6419 /* Set up the JPEG lib for reading an image from a FILE *.
6420 CINFO is the decompression info structure created for
6421 reading the image. */
6424 jpeg_file_src (j_decompress_ptr cinfo
, FILE *fp
)
6426 struct jpeg_stdio_mgr
*src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6430 /* First time for this JPEG object? */
6431 src
= cinfo
->mem
->alloc_small ((j_common_ptr
) cinfo
,
6432 JPOOL_PERMANENT
, sizeof *src
);
6433 cinfo
->src
= (struct jpeg_source_mgr
*) src
;
6434 src
->buffer
= cinfo
->mem
->alloc_small ((j_common_ptr
) cinfo
,
6436 JPEG_STDIO_BUFFER_SIZE
);
6441 src
->mgr
.init_source
= our_common_init_source
;
6442 src
->mgr
.fill_input_buffer
= our_stdio_fill_input_buffer
;
6443 src
->mgr
.skip_input_data
= our_stdio_skip_input_data
;
6444 src
->mgr
.resync_to_restart
= jpeg_resync_to_restart_wrapper
; /* Use default method. */
6445 src
->mgr
.term_source
= our_common_term_source
;
6446 src
->mgr
.bytes_in_buffer
= 0;
6447 src
->mgr
.next_input_byte
= NULL
;
6451 /* Load image IMG for use on frame F. Patterned after example.c
6452 from the JPEG lib. */
6455 jpeg_load_body (struct frame
*f
, struct image
*img
,
6456 struct my_jpeg_error_mgr
*mgr
)
6458 Lisp_Object file
, specified_file
;
6459 Lisp_Object specified_data
;
6462 int row_stride
, x
, y
;
6463 XImagePtr ximg
= NULL
;
6464 unsigned long *colors
;
6467 /* Open the JPEG file. */
6468 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6469 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6471 if (NILP (specified_data
))
6473 file
= x_find_image_file (specified_file
);
6474 if (!STRINGP (file
))
6476 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6480 fp
= emacs_fopen (SSDATA (file
), "rb");
6483 image_error ("Cannot open `%s'", file
, Qnil
);
6487 else if (!STRINGP (specified_data
))
6489 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
6493 IF_LINT (mgr
->fp
= fp
);
6495 /* Customize libjpeg's error handling to call my_error_exit when an
6496 error is detected. This function will perform a longjmp. */
6497 mgr
->cinfo
.err
= fn_jpeg_std_error (&mgr
->pub
);
6498 mgr
->pub
.error_exit
= my_error_exit
;
6499 if (sys_setjmp (mgr
->setjmp_buffer
))
6501 switch (mgr
->failure_code
)
6503 case MY_JPEG_ERROR_EXIT
:
6505 char buf
[JMSG_LENGTH_MAX
];
6506 mgr
->cinfo
.err
->format_message ((j_common_ptr
) &mgr
->cinfo
, buf
);
6507 image_error ("Error reading JPEG image `%s': %s", img
->spec
,
6508 build_string (buf
));
6512 case MY_JPEG_INVALID_IMAGE_SIZE
:
6513 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
6516 case MY_JPEG_CANNOT_CREATE_X
:
6520 /* Close the input file and destroy the JPEG object. */
6523 fn_jpeg_destroy_decompress (&mgr
->cinfo
);
6525 /* If we already have an XImage, free that. */
6526 x_destroy_x_image (ximg
);
6528 /* Free pixmap and colors. */
6529 x_clear_image (f
, img
);
6533 /* Silence a bogus diagnostic; see GCC bug 54561. */
6534 IF_LINT (fp
= mgr
->fp
);
6536 /* Create the JPEG decompression object. Let it read from fp.
6537 Read the JPEG image header. */
6538 fn_jpeg_CreateDecompress (&mgr
->cinfo
, JPEG_LIB_VERSION
, sizeof *&mgr
->cinfo
);
6540 if (NILP (specified_data
))
6541 jpeg_file_src (&mgr
->cinfo
, fp
);
6543 jpeg_memory_src (&mgr
->cinfo
, SDATA (specified_data
),
6544 SBYTES (specified_data
));
6546 fn_jpeg_read_header (&mgr
->cinfo
, 1);
6548 /* Customize decompression so that color quantization will be used.
6549 Start decompression. */
6550 mgr
->cinfo
.quantize_colors
= 1;
6551 fn_jpeg_start_decompress (&mgr
->cinfo
);
6552 width
= img
->width
= mgr
->cinfo
.output_width
;
6553 height
= img
->height
= mgr
->cinfo
.output_height
;
6555 if (!check_image_size (f
, width
, height
))
6557 mgr
->failure_code
= MY_JPEG_INVALID_IMAGE_SIZE
;
6558 sys_longjmp (mgr
->setjmp_buffer
, 1);
6561 /* Create X image and pixmap. */
6562 if (!image_create_x_image_and_pixmap (f
, img
, width
, height
, 0, &ximg
, 0))
6564 mgr
->failure_code
= MY_JPEG_CANNOT_CREATE_X
;
6565 sys_longjmp (mgr
->setjmp_buffer
, 1);
6568 /* Allocate colors. When color quantization is used,
6569 mgr->cinfo.actual_number_of_colors has been set with the number of
6570 colors generated, and mgr->cinfo.colormap is a two-dimensional array
6571 of color indices in the range 0..mgr->cinfo.actual_number_of_colors.
6572 No more than 255 colors will be generated. */
6576 if (mgr
->cinfo
.out_color_components
> 2)
6577 ir
= 0, ig
= 1, ib
= 2;
6578 else if (mgr
->cinfo
.out_color_components
> 1)
6579 ir
= 0, ig
= 1, ib
= 0;
6581 ir
= 0, ig
= 0, ib
= 0;
6583 /* Use the color table mechanism because it handles colors that
6584 cannot be allocated nicely. Such colors will be replaced with
6585 a default color, and we don't have to care about which colors
6586 can be freed safely, and which can't. */
6587 init_color_table ();
6588 colors
= alloca (mgr
->cinfo
.actual_number_of_colors
* sizeof *colors
);
6590 for (i
= 0; i
< mgr
->cinfo
.actual_number_of_colors
; ++i
)
6592 /* Multiply RGB values with 255 because X expects RGB values
6593 in the range 0..0xffff. */
6594 int r
= mgr
->cinfo
.colormap
[ir
][i
] << 8;
6595 int g
= mgr
->cinfo
.colormap
[ig
][i
] << 8;
6596 int b
= mgr
->cinfo
.colormap
[ib
][i
] << 8;
6597 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
6600 #ifdef COLOR_TABLE_SUPPORT
6601 /* Remember those colors actually allocated. */
6602 img
->colors
= colors_in_color_table (&img
->ncolors
);
6603 free_color_table ();
6604 #endif /* COLOR_TABLE_SUPPORT */
6608 row_stride
= width
* mgr
->cinfo
.output_components
;
6609 buffer
= mgr
->cinfo
.mem
->alloc_sarray ((j_common_ptr
) &mgr
->cinfo
,
6610 JPOOL_IMAGE
, row_stride
, 1);
6611 for (y
= 0; y
< height
; ++y
)
6613 fn_jpeg_read_scanlines (&mgr
->cinfo
, buffer
, 1);
6614 for (x
= 0; x
< mgr
->cinfo
.output_width
; ++x
)
6615 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
6619 fn_jpeg_finish_decompress (&mgr
->cinfo
);
6620 fn_jpeg_destroy_decompress (&mgr
->cinfo
);
6624 /* Maybe fill in the background field while we have ximg handy. */
6625 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6626 /* Casting avoids a GCC warning. */
6627 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6629 /* Put ximg into the image. */
6630 image_put_x_image (f
, img
, ximg
, 0);
6635 jpeg_load (struct frame
*f
, struct image
*img
)
6637 struct my_jpeg_error_mgr mgr
;
6638 return jpeg_load_body (f
, img
, &mgr
);
6641 #else /* HAVE_JPEG */
6645 jpeg_load (struct frame
*f
, struct image
*img
)
6647 return ns_load_image (f
, img
,
6648 image_spec_value (img
->spec
, QCfile
, NULL
),
6649 image_spec_value (img
->spec
, QCdata
, NULL
));
6651 #endif /* HAVE_NS */
6653 #endif /* !HAVE_JPEG */
6657 /***********************************************************************
6659 ***********************************************************************/
6661 #if defined (HAVE_TIFF) || defined (HAVE_NS)
6663 static bool tiff_image_p (Lisp_Object object
);
6664 static bool tiff_load (struct frame
*f
, struct image
*img
);
6666 /* The symbol `tiff' identifying images of this type. */
6668 static Lisp_Object Qtiff
;
6670 /* Indices of image specification fields in tiff_format, below. */
6672 enum tiff_keyword_index
6681 TIFF_HEURISTIC_MASK
,
6688 /* Vector of image_keyword structures describing the format
6689 of valid user-defined image specifications. */
6691 static const struct image_keyword tiff_format
[TIFF_LAST
] =
6693 {":type", IMAGE_SYMBOL_VALUE
, 1},
6694 {":data", IMAGE_STRING_VALUE
, 0},
6695 {":file", IMAGE_STRING_VALUE
, 0},
6696 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6697 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
6698 {":relief", IMAGE_INTEGER_VALUE
, 0},
6699 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6700 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6701 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6702 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
6703 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0}
6706 #if defined HAVE_NTGUI && defined WINDOWSNT
6707 static bool init_tiff_functions (void);
6709 #define init_tiff_functions NULL
6712 /* Structure describing the image type `tiff'. */
6714 static struct image_type tiff_type
=
6720 init_tiff_functions
,
6724 /* Return true if OBJECT is a valid TIFF image specification. */
6727 tiff_image_p (Lisp_Object object
)
6729 struct image_keyword fmt
[TIFF_LAST
];
6730 memcpy (fmt
, tiff_format
, sizeof fmt
);
6732 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
6735 /* Must specify either the :data or :file keyword. */
6736 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
6739 #endif /* HAVE_TIFF || HAVE_NS */
6747 /* TIFF library details. */
6748 DEF_IMGLIB_FN (TIFFErrorHandler
, TIFFSetErrorHandler
, (TIFFErrorHandler
));
6749 DEF_IMGLIB_FN (TIFFErrorHandler
, TIFFSetWarningHandler
, (TIFFErrorHandler
));
6750 DEF_IMGLIB_FN (TIFF
*, TIFFOpen
, (const char *, const char *));
6751 DEF_IMGLIB_FN (TIFF
*, TIFFClientOpen
, (const char *, const char *, thandle_t
,
6752 TIFFReadWriteProc
, TIFFReadWriteProc
,
6753 TIFFSeekProc
, TIFFCloseProc
, TIFFSizeProc
,
6754 TIFFMapFileProc
, TIFFUnmapFileProc
));
6755 DEF_IMGLIB_FN (int, TIFFGetField
, (TIFF
*, ttag_t
, ...));
6756 DEF_IMGLIB_FN (int, TIFFReadRGBAImage
, (TIFF
*, uint32
, uint32
, uint32
*, int));
6757 DEF_IMGLIB_FN (void, TIFFClose
, (TIFF
*));
6758 DEF_IMGLIB_FN (int, TIFFSetDirectory
, (TIFF
*, tdir_t
));
6761 init_tiff_functions (void)
6765 if (!(library
= w32_delayed_load (Qtiff
)))
6768 LOAD_IMGLIB_FN (library
, TIFFSetErrorHandler
);
6769 LOAD_IMGLIB_FN (library
, TIFFSetWarningHandler
);
6770 LOAD_IMGLIB_FN (library
, TIFFOpen
);
6771 LOAD_IMGLIB_FN (library
, TIFFClientOpen
);
6772 LOAD_IMGLIB_FN (library
, TIFFGetField
);
6773 LOAD_IMGLIB_FN (library
, TIFFReadRGBAImage
);
6774 LOAD_IMGLIB_FN (library
, TIFFClose
);
6775 LOAD_IMGLIB_FN (library
, TIFFSetDirectory
);
6781 #define fn_TIFFSetErrorHandler TIFFSetErrorHandler
6782 #define fn_TIFFSetWarningHandler TIFFSetWarningHandler
6783 #define fn_TIFFOpen TIFFOpen
6784 #define fn_TIFFClientOpen TIFFClientOpen
6785 #define fn_TIFFGetField TIFFGetField
6786 #define fn_TIFFReadRGBAImage TIFFReadRGBAImage
6787 #define fn_TIFFClose TIFFClose
6788 #define fn_TIFFSetDirectory TIFFSetDirectory
6789 #endif /* WINDOWSNT */
6792 /* Reading from a memory buffer for TIFF images Based on the PNG
6793 memory source, but we have to provide a lot of extra functions.
6796 We really only need to implement read and seek, but I am not
6797 convinced that the TIFF library is smart enough not to destroy
6798 itself if we only hand it the function pointers we need to
6803 unsigned char *bytes
;
6810 tiff_read_from_memory (thandle_t data
, tdata_t buf
, tsize_t size
)
6812 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6814 size
= min (size
, src
->len
- src
->index
);
6815 memcpy (buf
, src
->bytes
+ src
->index
, size
);
6821 tiff_write_from_memory (thandle_t data
, tdata_t buf
, tsize_t size
)
6827 tiff_seek_in_memory (thandle_t data
, toff_t off
, int whence
)
6829 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
6834 case SEEK_SET
: /* Go from beginning of source. */
6838 case SEEK_END
: /* Go from end of source. */
6839 idx
= src
->len
+ off
;
6842 case SEEK_CUR
: /* Go from current position. */
6843 idx
= src
->index
+ off
;
6846 default: /* Invalid `whence'. */
6850 if (idx
> src
->len
|| idx
< 0)
6858 tiff_close_memory (thandle_t data
)
6865 tiff_mmap_memory (thandle_t data
, tdata_t
*pbase
, toff_t
*psize
)
6867 /* It is already _IN_ memory. */
6872 tiff_unmap_memory (thandle_t data
, tdata_t base
, toff_t size
)
6874 /* We don't need to do this. */
6878 tiff_size_of_memory (thandle_t data
)
6880 return ((tiff_memory_source
*) data
)->len
;
6883 /* GCC 3.x on x86 Windows targets has a bug that triggers an internal
6884 compiler error compiling tiff_handler, see Bugzilla bug #17406
6885 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17406). Declaring
6886 this function as external works around that problem. */
6887 #if defined (__MINGW32__) && __GNUC__ == 3
6888 # define MINGW_STATIC
6890 # define MINGW_STATIC static
6894 tiff_handler (const char *, const char *, const char *, va_list)
6895 ATTRIBUTE_FORMAT_PRINTF (3, 0);
6897 tiff_handler (const char *log_format
, const char *title
,
6898 const char *format
, va_list ap
)
6900 /* doprnt is not suitable here, as TIFF handlers are called from
6901 libtiff and are passed arbitrary printf directives. Instead, use
6902 vsnprintf, taking care to be portable to nonstandard environments
6903 where vsnprintf returns -1 on buffer overflow. Since it's just a
6904 log entry, it's OK to truncate it. */
6906 int len
= vsnprintf (buf
, sizeof buf
, format
, ap
);
6907 add_to_log (log_format
, build_string (title
),
6908 make_string (buf
, max (0, min (len
, sizeof buf
- 1))));
6912 static void tiff_error_handler (const char *, const char *, va_list)
6913 ATTRIBUTE_FORMAT_PRINTF (2, 0);
6915 tiff_error_handler (const char *title
, const char *format
, va_list ap
)
6917 tiff_handler ("TIFF error: %s %s", title
, format
, ap
);
6921 static void tiff_warning_handler (const char *, const char *, va_list)
6922 ATTRIBUTE_FORMAT_PRINTF (2, 0);
6924 tiff_warning_handler (const char *title
, const char *format
, va_list ap
)
6926 tiff_handler ("TIFF warning: %s %s", title
, format
, ap
);
6930 /* Load TIFF image IMG for use on frame F. Value is true if
6934 tiff_load (struct frame
*f
, struct image
*img
)
6936 Lisp_Object file
, specified_file
;
6937 Lisp_Object specified_data
;
6939 int width
, height
, x
, y
, count
;
6943 tiff_memory_source memsrc
;
6946 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6947 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6949 fn_TIFFSetErrorHandler ((TIFFErrorHandler
) tiff_error_handler
);
6950 fn_TIFFSetWarningHandler ((TIFFErrorHandler
) tiff_warning_handler
);
6952 if (NILP (specified_data
))
6954 /* Read from a file */
6955 file
= x_find_image_file (specified_file
);
6956 if (!STRINGP (file
))
6958 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
6962 /* Try to open the image file. */
6963 tiff
= fn_TIFFOpen (SSDATA (file
), "r");
6966 image_error ("Cannot open `%s'", file
, Qnil
);
6972 if (!STRINGP (specified_data
))
6974 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
6978 /* Memory source! */
6979 memsrc
.bytes
= SDATA (specified_data
);
6980 memsrc
.len
= SBYTES (specified_data
);
6983 tiff
= fn_TIFFClientOpen ("memory_source", "r", (thandle_t
)&memsrc
,
6984 tiff_read_from_memory
,
6985 tiff_write_from_memory
,
6986 tiff_seek_in_memory
,
6988 tiff_size_of_memory
,
6994 image_error ("Cannot open memory source for `%s'", img
->spec
, Qnil
);
6999 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
7000 if (INTEGERP (image
))
7002 EMACS_INT ino
= XFASTINT (image
);
7003 if (! (TYPE_MINIMUM (tdir_t
) <= ino
&& ino
<= TYPE_MAXIMUM (tdir_t
)
7004 && fn_TIFFSetDirectory (tiff
, ino
)))
7006 image_error ("Invalid image number `%s' in image `%s'",
7008 fn_TIFFClose (tiff
);
7013 /* Get width and height of the image, and allocate a raster buffer
7014 of width x height 32-bit values. */
7015 fn_TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
7016 fn_TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
7018 if (!check_image_size (f
, width
, height
))
7020 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7021 fn_TIFFClose (tiff
);
7025 /* Create the X image and pixmap. */
7026 if (! (height
<= min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *buf
/ width
7027 && image_create_x_image_and_pixmap (f
, img
, width
, height
, 0,
7030 fn_TIFFClose (tiff
);
7034 buf
= xmalloc (sizeof *buf
* width
* height
);
7036 rc
= fn_TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
7038 /* Count the number of images in the file. */
7039 for (count
= 1; fn_TIFFSetDirectory (tiff
, count
); count
++)
7043 img
->lisp_data
= Fcons (Qcount
,
7044 Fcons (make_number (count
),
7047 fn_TIFFClose (tiff
);
7050 image_error ("Error reading TIFF image `%s'", img
->spec
, Qnil
);
7055 /* Initialize the color table. */
7056 init_color_table ();
7058 /* Process the pixel raster. Origin is in the lower-left corner. */
7059 for (y
= 0; y
< height
; ++y
)
7061 uint32
*row
= buf
+ y
* width
;
7063 for (x
= 0; x
< width
; ++x
)
7065 uint32 abgr
= row
[x
];
7066 int r
= TIFFGetR (abgr
) << 8;
7067 int g
= TIFFGetG (abgr
) << 8;
7068 int b
= TIFFGetB (abgr
) << 8;
7069 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
7073 #ifdef COLOR_TABLE_SUPPORT
7074 /* Remember the colors allocated for the image. Free the color table. */
7075 img
->colors
= colors_in_color_table (&img
->ncolors
);
7076 free_color_table ();
7077 #endif /* COLOR_TABLE_SUPPORT */
7080 img
->height
= height
;
7082 /* Maybe fill in the background field while we have ximg handy. */
7083 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7084 /* Casting avoids a GCC warning on W32. */
7085 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
7087 /* Put ximg into the image. */
7088 image_put_x_image (f
, img
, ximg
, 0);
7094 #else /* HAVE_TIFF */
7098 tiff_load (struct frame
*f
, struct image
*img
)
7100 return ns_load_image (f
, img
,
7101 image_spec_value (img
->spec
, QCfile
, NULL
),
7102 image_spec_value (img
->spec
, QCdata
, NULL
));
7104 #endif /* HAVE_NS */
7106 #endif /* !HAVE_TIFF */
7110 /***********************************************************************
7112 ***********************************************************************/
7114 #if defined (HAVE_GIF) || defined (HAVE_NS)
7116 static bool gif_image_p (Lisp_Object object
);
7117 static bool gif_load (struct frame
*f
, struct image
*img
);
7118 static void gif_clear_image (struct frame
*f
, struct image
*img
);
7120 /* The symbol `gif' identifying images of this type. */
7122 static Lisp_Object Qgif
;
7124 /* Indices of image specification fields in gif_format, below. */
7126 enum gif_keyword_index
7142 /* Vector of image_keyword structures describing the format
7143 of valid user-defined image specifications. */
7145 static const struct image_keyword gif_format
[GIF_LAST
] =
7147 {":type", IMAGE_SYMBOL_VALUE
, 1},
7148 {":data", IMAGE_STRING_VALUE
, 0},
7149 {":file", IMAGE_STRING_VALUE
, 0},
7150 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7151 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
7152 {":relief", IMAGE_INTEGER_VALUE
, 0},
7153 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7154 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7155 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7156 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7157 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7160 #if defined HAVE_NTGUI && defined WINDOWSNT
7161 static bool init_gif_functions (void);
7163 #define init_gif_functions NULL
7166 /* Structure describing the image type `gif'. */
7168 static struct image_type gif_type
=
7178 /* Free X resources of GIF image IMG which is used on frame F. */
7181 gif_clear_image (struct frame
*f
, struct image
*img
)
7183 img
->lisp_data
= Qnil
;
7184 x_clear_image (f
, img
);
7187 /* Return true if OBJECT is a valid GIF image specification. */
7190 gif_image_p (Lisp_Object object
)
7192 struct image_keyword fmt
[GIF_LAST
];
7193 memcpy (fmt
, gif_format
, sizeof fmt
);
7195 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
7198 /* Must specify either the :data or :file keyword. */
7199 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
7202 #endif /* HAVE_GIF */
7206 #if defined (HAVE_NTGUI)
7208 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
7209 Undefine before redefining to avoid a preprocessor warning. */
7213 /* avoid conflict with QuickdrawText.h */
7214 #define DrawText gif_DrawText
7215 #include <gif_lib.h>
7218 /* Giflib before 5.0 didn't define these macros (used only if HAVE_NTGUI). */
7219 #ifndef GIFLIB_MINOR
7220 #define GIFLIB_MINOR 0
7222 #ifndef GIFLIB_RELEASE
7223 #define GIFLIB_RELEASE 0
7226 #else /* HAVE_NTGUI */
7228 #include <gif_lib.h>
7230 #endif /* HAVE_NTGUI */
7232 /* Giflib before 5.0 didn't define these macros. */
7233 #ifndef GIFLIB_MAJOR
7234 #define GIFLIB_MAJOR 4
7239 /* GIF library details. */
7240 DEF_IMGLIB_FN (int, DGifCloseFile
, (GifFileType
*));
7241 DEF_IMGLIB_FN (int, DGifSlurp
, (GifFileType
*));
7242 #if GIFLIB_MAJOR < 5
7243 DEF_IMGLIB_FN (GifFileType
*, DGifOpen
, (void *, InputFunc
));
7244 DEF_IMGLIB_FN (GifFileType
*, DGifOpenFileName
, (const char *));
7246 DEF_IMGLIB_FN (GifFileType
*, DGifOpen
, (void *, InputFunc
, int *));
7247 DEF_IMGLIB_FN (GifFileType
*, DGifOpenFileName
, (const char *, int *));
7248 DEF_IMGLIB_FN (char *, GifErrorString
, (int));
7252 init_gif_functions (void)
7256 if (!(library
= w32_delayed_load (Qgif
)))
7259 LOAD_IMGLIB_FN (library
, DGifCloseFile
);
7260 LOAD_IMGLIB_FN (library
, DGifSlurp
);
7261 LOAD_IMGLIB_FN (library
, DGifOpen
);
7262 LOAD_IMGLIB_FN (library
, DGifOpenFileName
);
7263 #if GIFLIB_MAJOR >= 5
7264 LOAD_IMGLIB_FN (library
, GifErrorString
);
7271 #define fn_DGifCloseFile DGifCloseFile
7272 #define fn_DGifSlurp DGifSlurp
7273 #define fn_DGifOpen DGifOpen
7274 #define fn_DGifOpenFileName DGifOpenFileName
7275 #if 5 <= GIFLIB_MAJOR
7276 # define fn_GifErrorString GifErrorString
7279 #endif /* WINDOWSNT */
7281 /* Reading a GIF image from memory
7282 Based on the PNG memory stuff to a certain extent. */
7286 unsigned char *bytes
;
7292 /* Make the current memory source available to gif_read_from_memory.
7293 It's done this way because not all versions of libungif support
7294 a UserData field in the GifFileType structure. */
7295 static gif_memory_source
*current_gif_memory_src
;
7298 gif_read_from_memory (GifFileType
*file
, GifByteType
*buf
, int len
)
7300 gif_memory_source
*src
= current_gif_memory_src
;
7302 if (len
> src
->len
- src
->index
)
7305 memcpy (buf
, src
->bytes
+ src
->index
, len
);
7311 /* Load GIF image IMG for use on frame F. Value is true if
7314 static const int interlace_start
[] = {0, 4, 2, 1};
7315 static const int interlace_increment
[] = {8, 8, 4, 2};
7317 #define GIF_LOCAL_DESCRIPTOR_EXTENSION 249
7320 gif_load (struct frame
*f
, struct image
*img
)
7323 int rc
, width
, height
, x
, y
, i
, j
;
7325 ColorMapObject
*gif_color_map
;
7326 unsigned long pixel_colors
[256];
7328 gif_memory_source memsrc
;
7329 Lisp_Object specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
7330 Lisp_Object specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7331 Lisp_Object specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7332 unsigned long bgcolor
= 0;
7334 #if GIFLIB_MAJOR >= 5
7338 if (NILP (specified_data
))
7340 file
= x_find_image_file (specified_file
);
7341 if (!STRINGP (file
))
7343 image_error ("Cannot find image file `%s'", specified_file
, Qnil
);
7347 /* Open the GIF file. */
7348 #if GIFLIB_MAJOR < 5
7349 gif
= fn_DGifOpenFileName (SSDATA (file
));
7352 image_error ("Cannot open `%s'", file
, Qnil
);
7356 gif
= fn_DGifOpenFileName (SSDATA (file
), &gif_err
);
7359 image_error ("Cannot open `%s': %s",
7360 file
, build_string (fn_GifErrorString (gif_err
)));
7367 if (!STRINGP (specified_data
))
7369 image_error ("Invalid image data `%s'", specified_data
, Qnil
);
7373 /* Read from memory! */
7374 current_gif_memory_src
= &memsrc
;
7375 memsrc
.bytes
= SDATA (specified_data
);
7376 memsrc
.len
= SBYTES (specified_data
);
7379 #if GIFLIB_MAJOR < 5
7380 gif
= fn_DGifOpen (&memsrc
, gif_read_from_memory
);
7383 image_error ("Cannot open memory source `%s'", img
->spec
, Qnil
);
7387 gif
= fn_DGifOpen (&memsrc
, gif_read_from_memory
, &gif_err
);
7390 image_error ("Cannot open memory source `%s': %s",
7391 img
->spec
, build_string (fn_GifErrorString (gif_err
)));
7397 /* Before reading entire contents, check the declared image size. */
7398 if (!check_image_size (f
, gif
->SWidth
, gif
->SHeight
))
7400 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7401 fn_DGifCloseFile (gif
);
7405 /* Read entire contents. */
7406 rc
= fn_DGifSlurp (gif
);
7407 if (rc
== GIF_ERROR
|| gif
->ImageCount
<= 0)
7409 image_error ("Error reading `%s'", img
->spec
, Qnil
);
7410 fn_DGifCloseFile (gif
);
7414 /* Which sub-image are we to display? */
7416 Lisp_Object image_number
= image_spec_value (img
->spec
, QCindex
, NULL
);
7417 idx
= INTEGERP (image_number
) ? XFASTINT (image_number
) : 0;
7418 if (idx
< 0 || idx
>= gif
->ImageCount
)
7420 image_error ("Invalid image number `%s' in image `%s'",
7421 image_number
, img
->spec
);
7422 fn_DGifCloseFile (gif
);
7427 width
= img
->width
= gif
->SWidth
;
7428 height
= img
->height
= gif
->SHeight
;
7430 img
->corners
[TOP_CORNER
] = gif
->SavedImages
[0].ImageDesc
.Top
;
7431 img
->corners
[LEFT_CORNER
] = gif
->SavedImages
[0].ImageDesc
.Left
;
7432 img
->corners
[BOT_CORNER
]
7433 = img
->corners
[TOP_CORNER
] + gif
->SavedImages
[0].ImageDesc
.Height
;
7434 img
->corners
[RIGHT_CORNER
]
7435 = img
->corners
[LEFT_CORNER
] + gif
->SavedImages
[0].ImageDesc
.Width
;
7437 if (!check_image_size (f
, width
, height
))
7439 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
7440 fn_DGifCloseFile (gif
);
7444 /* Check that the selected subimages fit. It's not clear whether
7445 the GIF spec requires this, but Emacs can crash if they don't fit. */
7446 for (j
= 0; j
<= idx
; ++j
)
7448 struct SavedImage
*subimage
= gif
->SavedImages
+ j
;
7449 int subimg_width
= subimage
->ImageDesc
.Width
;
7450 int subimg_height
= subimage
->ImageDesc
.Height
;
7451 int subimg_top
= subimage
->ImageDesc
.Top
;
7452 int subimg_left
= subimage
->ImageDesc
.Left
;
7453 if (! (0 <= subimg_width
&& 0 <= subimg_height
7454 && 0 <= subimg_top
&& subimg_top
<= height
- subimg_height
7455 && 0 <= subimg_left
&& subimg_left
<= width
- subimg_width
))
7457 image_error ("Subimage does not fit in image", Qnil
, Qnil
);
7458 fn_DGifCloseFile (gif
);
7463 /* Create the X image and pixmap. */
7464 if (!image_create_x_image_and_pixmap (f
, img
, width
, height
, 0, &ximg
, 0))
7466 fn_DGifCloseFile (gif
);
7470 /* Clear the part of the screen image not covered by the image.
7471 Full animated GIF support requires more here (see the gif89 spec,
7472 disposal methods). Let's simply assume that the part not covered
7473 by a sub-image is in the frame's background color. */
7474 for (y
= 0; y
< img
->corners
[TOP_CORNER
]; ++y
)
7475 for (x
= 0; x
< width
; ++x
)
7476 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7478 for (y
= img
->corners
[BOT_CORNER
]; y
< height
; ++y
)
7479 for (x
= 0; x
< width
; ++x
)
7480 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7482 for (y
= img
->corners
[TOP_CORNER
]; y
< img
->corners
[BOT_CORNER
]; ++y
)
7484 for (x
= 0; x
< img
->corners
[LEFT_CORNER
]; ++x
)
7485 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7486 for (x
= img
->corners
[RIGHT_CORNER
]; x
< width
; ++x
)
7487 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7490 /* Read the GIF image into the X image. */
7492 /* FIXME: With the current implementation, loading an animated gif
7493 is quadratic in the number of animation frames, since each frame
7494 is a separate struct image. We must provide a way for a single
7495 gif_load call to construct and save all animation frames. */
7497 init_color_table ();
7498 if (STRINGP (specified_bg
))
7499 bgcolor
= x_alloc_image_color (f
, img
, specified_bg
,
7500 FRAME_BACKGROUND_PIXEL (f
));
7501 for (j
= 0; j
<= idx
; ++j
)
7503 /* We use a local variable `raster' here because RasterBits is a
7504 char *, which invites problems with bytes >= 0x80. */
7505 struct SavedImage
*subimage
= gif
->SavedImages
+ j
;
7506 unsigned char *raster
= (unsigned char *) subimage
->RasterBits
;
7507 int transparency_color_index
= -1;
7509 int subimg_width
= subimage
->ImageDesc
.Width
;
7510 int subimg_height
= subimage
->ImageDesc
.Height
;
7511 int subimg_top
= subimage
->ImageDesc
.Top
;
7512 int subimg_left
= subimage
->ImageDesc
.Left
;
7514 /* Find the Graphic Control Extension block for this sub-image.
7515 Extract the disposal method and transparency color. */
7516 for (i
= 0; i
< subimage
->ExtensionBlockCount
; i
++)
7518 ExtensionBlock
*extblock
= subimage
->ExtensionBlocks
+ i
;
7520 if ((extblock
->Function
== GIF_LOCAL_DESCRIPTOR_EXTENSION
)
7521 && extblock
->ByteCount
== 4
7522 && extblock
->Bytes
[0] & 1)
7524 /* From gif89a spec: 1 = "keep in place", 2 = "restore
7525 to background". Treat any other value like 2. */
7526 disposal
= (extblock
->Bytes
[0] >> 2) & 7;
7527 transparency_color_index
= (unsigned char) extblock
->Bytes
[3];
7532 /* We can't "keep in place" the first subimage. */
7536 /* For disposal == 0, the spec says "No disposal specified. The
7537 decoder is not required to take any action." In practice, it
7538 seems we need to treat this like "keep in place", see e.g.
7539 http://upload.wikimedia.org/wikipedia/commons/3/37/Clock.gif */
7543 /* Allocate subimage colors. */
7544 memset (pixel_colors
, 0, sizeof pixel_colors
);
7545 gif_color_map
= subimage
->ImageDesc
.ColorMap
;
7547 gif_color_map
= gif
->SColorMap
;
7550 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
7552 if (transparency_color_index
== i
)
7553 pixel_colors
[i
] = STRINGP (specified_bg
)
7554 ? bgcolor
: FRAME_BACKGROUND_PIXEL (f
);
7557 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
7558 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
7559 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
7560 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
7564 /* Apply the pixel values. */
7565 if (gif
->SavedImages
[j
].ImageDesc
.Interlace
)
7569 for (y
= 0, row
= interlace_start
[0], pass
= 0;
7571 y
++, row
+= interlace_increment
[pass
])
7573 while (subimg_height
<= row
)
7574 row
= interlace_start
[++pass
];
7576 for (x
= 0; x
< subimg_width
; x
++)
7578 int c
= raster
[y
* subimg_width
+ x
];
7579 if (transparency_color_index
!= c
|| disposal
!= 1)
7580 XPutPixel (ximg
, x
+ subimg_left
, row
+ subimg_top
,
7587 for (y
= 0; y
< subimg_height
; ++y
)
7588 for (x
= 0; x
< subimg_width
; ++x
)
7590 int c
= raster
[y
* subimg_width
+ x
];
7591 if (transparency_color_index
!= c
|| disposal
!= 1)
7592 XPutPixel (ximg
, x
+ subimg_left
, y
+ subimg_top
,
7598 #ifdef COLOR_TABLE_SUPPORT
7599 img
->colors
= colors_in_color_table (&img
->ncolors
);
7600 free_color_table ();
7601 #endif /* COLOR_TABLE_SUPPORT */
7603 /* Save GIF image extension data for `image-metadata'.
7604 Format is (count IMAGES extension-data (FUNCTION "BYTES" ...)). */
7605 img
->lisp_data
= Qnil
;
7606 if (gif
->SavedImages
[idx
].ExtensionBlockCount
> 0)
7609 ExtensionBlock
*ext
= gif
->SavedImages
[idx
].ExtensionBlocks
;
7610 for (i
= 0; i
< gif
->SavedImages
[idx
].ExtensionBlockCount
; i
++, ext
++)
7611 /* Append (... FUNCTION "BYTES") */
7614 = Fcons (make_number (ext
->Function
),
7615 Fcons (make_unibyte_string (ext
->Bytes
, ext
->ByteCount
),
7617 if (ext
->Function
== GIF_LOCAL_DESCRIPTOR_EXTENSION
7618 && ext
->ByteCount
== 4)
7620 delay
= ext
->Bytes
[2] << CHAR_BIT
;
7621 delay
|= ext
->Bytes
[1];
7624 img
->lisp_data
= list2 (Qextension_data
, img
->lisp_data
);
7628 Fcons (make_float (delay
/ 100.0),
7632 if (gif
->ImageCount
> 1)
7633 img
->lisp_data
= Fcons (Qcount
,
7634 Fcons (make_number (gif
->ImageCount
),
7637 fn_DGifCloseFile (gif
);
7639 /* Maybe fill in the background field while we have ximg handy. */
7640 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7641 /* Casting avoids a GCC warning. */
7642 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
7644 /* Put ximg into the image. */
7645 image_put_x_image (f
, img
, ximg
, 0);
7650 #else /* !HAVE_GIF */
7654 gif_load (struct frame
*f
, struct image
*img
)
7656 return ns_load_image (f
, img
,
7657 image_spec_value (img
->spec
, QCfile
, NULL
),
7658 image_spec_value (img
->spec
, QCdata
, NULL
));
7660 #endif /* HAVE_NS */
7662 #endif /* HAVE_GIF */
7665 #ifdef HAVE_IMAGEMAGICK
7667 /***********************************************************************
7669 ***********************************************************************/
7671 /* Scale an image size by returning SIZE / DIVISOR * MULTIPLIER,
7672 safely rounded and clipped to int range. */
7675 scale_image_size (int size
, size_t divisor
, size_t multiplier
)
7680 double scaled
= s
* multiplier
/ divisor
+ 0.5;
7681 if (scaled
< INT_MAX
)
7687 /* Compute the desired size of an image with native size WIDTH x HEIGHT.
7688 Use SPEC to deduce the size. Store the desired size into
7689 *D_WIDTH x *D_HEIGHT. Store -1 x -1 if the native size is OK. */
7691 compute_image_size (size_t width
, size_t height
,
7693 int *d_width
, int *d_height
)
7696 int desired_width
, desired_height
;
7698 /* If width and/or height is set in the display spec assume we want
7699 to scale to those values. If either h or w is unspecified, the
7700 unspecified should be calculated from the specified to preserve
7702 value
= image_spec_value (spec
, QCwidth
, NULL
);
7703 desired_width
= NATNUMP (value
) ? min (XFASTINT (value
), INT_MAX
) : -1;
7704 value
= image_spec_value (spec
, QCheight
, NULL
);
7705 desired_height
= NATNUMP (value
) ? min (XFASTINT (value
), INT_MAX
) : -1;
7707 if (desired_width
== -1)
7709 value
= image_spec_value (spec
, QCmax_width
, NULL
);
7710 if (NATNUMP (value
))
7712 int max_width
= min (XFASTINT (value
), INT_MAX
);
7713 if (max_width
< width
)
7715 /* The image is wider than :max-width. */
7716 desired_width
= max_width
;
7717 if (desired_height
== -1)
7719 desired_height
= scale_image_size (desired_width
,
7721 value
= image_spec_value (spec
, QCmax_height
, NULL
);
7722 if (NATNUMP (value
))
7724 int max_height
= min (XFASTINT (value
), INT_MAX
);
7725 if (max_height
< desired_height
)
7727 desired_height
= max_height
;
7728 desired_width
= scale_image_size (desired_height
,
7737 if (desired_height
== -1)
7739 value
= image_spec_value (spec
, QCmax_height
, NULL
);
7740 if (NATNUMP (value
))
7742 int max_height
= min (XFASTINT (value
), INT_MAX
);
7743 if (max_height
< height
)
7744 desired_height
= max_height
;
7748 if (desired_width
!= -1 && desired_height
== -1)
7749 /* w known, calculate h. */
7750 desired_height
= scale_image_size (desired_width
, width
, height
);
7752 if (desired_width
== -1 && desired_height
!= -1)
7753 /* h known, calculate w. */
7754 desired_width
= scale_image_size (desired_height
, height
, width
);
7756 *d_width
= desired_width
;
7757 *d_height
= desired_height
;
7760 static Lisp_Object Qimagemagick
;
7762 static bool imagemagick_image_p (Lisp_Object
);
7763 static bool imagemagick_load (struct frame
*, struct image
*);
7764 static void imagemagick_clear_image (struct frame
*, struct image
*);
7766 /* Indices of image specification fields in imagemagick_format. */
7768 enum imagemagick_keyword_index
7776 IMAGEMAGICK_ALGORITHM
,
7777 IMAGEMAGICK_HEURISTIC_MASK
,
7779 IMAGEMAGICK_BACKGROUND
,
7782 IMAGEMAGICK_MAX_HEIGHT
,
7783 IMAGEMAGICK_MAX_WIDTH
,
7785 IMAGEMAGICK_ROTATION
,
7790 /* Vector of image_keyword structures describing the format
7791 of valid user-defined image specifications. */
7793 static struct image_keyword imagemagick_format
[IMAGEMAGICK_LAST
] =
7795 {":type", IMAGE_SYMBOL_VALUE
, 1},
7796 {":data", IMAGE_STRING_VALUE
, 0},
7797 {":file", IMAGE_STRING_VALUE
, 0},
7798 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7799 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
7800 {":relief", IMAGE_INTEGER_VALUE
, 0},
7801 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7802 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7803 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7804 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
7805 {":height", IMAGE_INTEGER_VALUE
, 0},
7806 {":width", IMAGE_INTEGER_VALUE
, 0},
7807 {":max-height", IMAGE_INTEGER_VALUE
, 0},
7808 {":max-width", IMAGE_INTEGER_VALUE
, 0},
7809 {":format", IMAGE_SYMBOL_VALUE
, 0},
7810 {":rotation", IMAGE_NUMBER_VALUE
, 0},
7811 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
7814 #if defined HAVE_NTGUI && defined WINDOWSNT
7815 static bool init_imagemagick_functions (void);
7817 #define init_imagemagick_functions NULL
7820 /* Structure describing the image type for any image handled via
7823 static struct image_type imagemagick_type
=
7826 imagemagick_image_p
,
7828 imagemagick_clear_image
,
7829 init_imagemagick_functions
,
7833 /* Free X resources of imagemagick image IMG which is used on frame F. */
7836 imagemagick_clear_image (struct frame
*f
,
7839 x_clear_image (f
, img
);
7842 /* Return true if OBJECT is a valid IMAGEMAGICK image specification. Do
7843 this by calling parse_image_spec and supplying the keywords that
7844 identify the IMAGEMAGICK format. */
7847 imagemagick_image_p (Lisp_Object object
)
7849 struct image_keyword fmt
[IMAGEMAGICK_LAST
];
7850 memcpy (fmt
, imagemagick_format
, sizeof fmt
);
7852 if (!parse_image_spec (object
, fmt
, IMAGEMAGICK_LAST
, Qimagemagick
))
7855 /* Must specify either the :data or :file keyword. */
7856 return fmt
[IMAGEMAGICK_FILE
].count
+ fmt
[IMAGEMAGICK_DATA
].count
== 1;
7859 /* The GIF library also defines DrawRectangle, but its never used in Emacs.
7860 Therefore rename the function so it doesn't collide with ImageMagick. */
7861 #define DrawRectangle DrawRectangleGif
7862 #include <wand/MagickWand.h>
7864 /* ImageMagick 6.5.3 through 6.6.5 hid PixelGetMagickColor for some reason.
7865 Emacs seems to work fine with the hidden version, so unhide it. */
7866 #include <magick/version.h>
7867 #if 0x653 <= MagickLibVersion && MagickLibVersion <= 0x665
7868 extern WandExport
void PixelGetMagickColor (const PixelWand
*,
7869 MagickPixelPacket
*);
7872 /* Log ImageMagick error message.
7873 Useful when a ImageMagick function returns the status `MagickFalse'. */
7876 imagemagick_error (MagickWand
*wand
)
7879 ExceptionType severity
;
7881 description
= MagickGetException (wand
, &severity
);
7882 image_error ("ImageMagick error: %s",
7883 build_string (description
),
7885 description
= (char *) MagickRelinquishMemory (description
);
7888 /* Possibly give ImageMagick some extra help to determine the image
7889 type by supplying a "dummy" filename based on the Content-Type. */
7892 imagemagick_filename_hint (Lisp_Object spec
, char hint_buffer
[MaxTextExtent
])
7894 Lisp_Object symbol
= intern ("image-format-suffixes");
7895 Lisp_Object val
= find_symbol_value (symbol
);
7901 format
= image_spec_value (spec
, intern (":format"), NULL
);
7902 val
= Fcar_safe (Fcdr_safe (Fassq (format
, val
)));
7903 if (! STRINGP (val
))
7906 /* It's OK to truncate the hint if it has MaxTextExtent or more bytes,
7907 as ImageMagick would ignore the extra bytes anyway. */
7908 snprintf (hint_buffer
, MaxTextExtent
, "/tmp/foo.%s", SSDATA (val
));
7912 /* Animated images (e.g., GIF89a) are composed from one "master image"
7913 (which is the first one, and then there's a number of images that
7914 follow. If following images have non-transparent colors, these are
7915 composed "on top" of the master image. So, in general, one has to
7916 compute ann the preceding images to be able to display a particular
7919 Computing all the preceding images is too slow, so we maintain a
7920 cache of previously computed images. We have to maintain a cache
7921 separate from the image cache, because the images may be scaled
7924 struct animation_cache
7928 struct timespec update_time
;
7929 struct animation_cache
*next
;
7930 char signature
[FLEXIBLE_ARRAY_MEMBER
];
7933 static struct animation_cache
*animation_cache
= NULL
;
7935 static struct animation_cache
*
7936 imagemagick_create_cache (char *signature
)
7938 struct animation_cache
*cache
7939 = xmalloc (offsetof (struct animation_cache
, signature
)
7940 + strlen (signature
) + 1);
7944 strcpy (cache
->signature
, signature
);
7948 /* Discard cached images that haven't been used for a minute. */
7950 imagemagick_prune_animation_cache (void)
7952 struct animation_cache
**pcache
= &animation_cache
;
7953 struct timespec old
= timespec_sub (current_timespec (),
7954 make_timespec (60, 0));
7958 struct animation_cache
*cache
= *pcache
;
7959 if (timespec_cmp (old
, cache
->update_time
) <= 0)
7960 pcache
= &cache
->next
;
7964 DestroyMagickWand (cache
->wand
);
7965 *pcache
= cache
->next
;
7971 static struct animation_cache
*
7972 imagemagick_get_animation_cache (MagickWand
*wand
)
7974 char *signature
= MagickGetImageSignature (wand
);
7975 struct animation_cache
*cache
;
7976 struct animation_cache
**pcache
= &animation_cache
;
7978 imagemagick_prune_animation_cache ();
7985 *pcache
= cache
= imagemagick_create_cache (signature
);
7988 if (strcmp (signature
, cache
->signature
) == 0)
7990 pcache
= &cache
->next
;
7993 DestroyString (signature
);
7994 cache
->update_time
= current_timespec ();
7999 imagemagick_compute_animated_image (MagickWand
*super_wand
, int ino
)
8002 MagickWand
*composite_wand
;
8003 size_t dest_width
, dest_height
;
8004 struct animation_cache
*cache
= imagemagick_get_animation_cache (super_wand
);
8006 MagickSetIteratorIndex (super_wand
, 0);
8008 if (ino
== 0 || cache
->wand
== NULL
|| cache
->index
> ino
)
8010 composite_wand
= MagickGetImage (super_wand
);
8012 DestroyMagickWand (cache
->wand
);
8015 composite_wand
= cache
->wand
;
8017 dest_width
= MagickGetImageWidth (composite_wand
);
8018 dest_height
= MagickGetImageHeight (composite_wand
);
8020 for (i
= max (1, cache
->index
+ 1); i
<= ino
; i
++)
8022 MagickWand
*sub_wand
;
8023 PixelIterator
*source_iterator
, *dest_iterator
;
8024 PixelWand
**source
, **dest
;
8025 size_t source_width
, source_height
;
8026 ssize_t source_left
, source_top
;
8027 MagickPixelPacket pixel
;
8028 DisposeType dispose
;
8029 ptrdiff_t lines
= 0;
8031 MagickSetIteratorIndex (super_wand
, i
);
8032 sub_wand
= MagickGetImage (super_wand
);
8034 MagickGetImagePage (sub_wand
, &source_width
, &source_height
,
8035 &source_left
, &source_top
);
8037 /* This flag says how to handle transparent pixels. */
8038 dispose
= MagickGetImageDispose (sub_wand
);
8040 source_iterator
= NewPixelIterator (sub_wand
);
8041 if (! source_iterator
)
8043 DestroyMagickWand (composite_wand
);
8044 DestroyMagickWand (sub_wand
);
8046 image_error ("Imagemagick pixel iterator creation failed",
8051 dest_iterator
= NewPixelIterator (composite_wand
);
8052 if (! dest_iterator
)
8054 DestroyMagickWand (composite_wand
);
8055 DestroyMagickWand (sub_wand
);
8056 DestroyPixelIterator (source_iterator
);
8058 image_error ("Imagemagick pixel iterator creation failed",
8063 /* The sub-image may not start at origin, so move the destination
8064 iterator to where the sub-image should start. */
8067 PixelSetIteratorRow (dest_iterator
, source_top
);
8071 while ((source
= PixelGetNextIteratorRow (source_iterator
, &source_width
))
8076 /* Sanity check. This shouldn't happen, but apparently
8077 does in some pictures. */
8078 if (++lines
>= dest_height
)
8081 dest
= PixelGetNextIteratorRow (dest_iterator
, &dest_width
);
8082 for (x
= 0; x
< source_width
; x
++)
8084 /* Sanity check. This shouldn't happen, but apparently
8085 also does in some pictures. */
8086 if (x
+ source_left
> dest_width
)
8088 /* Normally we only copy over non-transparent pixels,
8089 but if the disposal method is "Background", then we
8090 copy over all pixels. */
8091 if (dispose
== BackgroundDispose
||
8092 PixelGetAlpha (source
[x
]))
8094 PixelGetMagickColor (source
[x
], &pixel
);
8095 PixelSetMagickColor (dest
[x
+ source_left
], &pixel
);
8098 PixelSyncIterator (dest_iterator
);
8101 DestroyPixelIterator (source_iterator
);
8102 DestroyPixelIterator (dest_iterator
);
8103 DestroyMagickWand (sub_wand
);
8106 /* Cache a copy for the next iteration. The current wand will be
8107 destroyed by the caller. */
8108 cache
->wand
= CloneMagickWand (composite_wand
);
8111 return composite_wand
;
8115 /* Helper function for imagemagick_load, which does the actual loading
8116 given contents and size, apart from frame and image structures,
8117 passed from imagemagick_load. Uses librimagemagick to do most of
8118 the image processing.
8120 F is a pointer to the Emacs frame; IMG to the image structure to
8121 prepare; CONTENTS is the string containing the IMAGEMAGICK data to
8122 be parsed; SIZE is the number of bytes of data; and FILENAME is
8123 either the file name or the image data.
8125 Return true if successful. */
8128 imagemagick_load_image (struct frame
*f
, struct image
*img
,
8129 unsigned char *contents
, unsigned int size
,
8132 size_t width
, height
;
8133 MagickBooleanType status
;
8136 MagickWand
*image_wand
;
8137 PixelIterator
*iterator
;
8138 PixelWand
**pixels
, *bg_wand
= NULL
;
8139 MagickPixelPacket pixel
;
8144 int desired_width
, desired_height
;
8147 char hint_buffer
[MaxTextExtent
];
8148 char *filename_hint
= NULL
;
8150 /* Handle image index for image types who can contain more than one image.
8151 Interface :index is same as for GIF. First we "ping" the image to see how
8152 many sub-images it contains. Pinging is faster than loading the image to
8153 find out things about it. */
8155 /* Initialize the imagemagick environment. */
8156 MagickWandGenesis ();
8157 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
8158 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
8159 image_wand
= NewMagickWand ();
8162 status
= MagickReadImage (image_wand
, filename
);
8165 filename_hint
= imagemagick_filename_hint (img
->spec
, hint_buffer
);
8166 MagickSetFilename (image_wand
, filename_hint
);
8167 status
= MagickReadImageBlob (image_wand
, contents
, size
);
8170 if (status
== MagickFalse
)
8172 imagemagick_error (image_wand
);
8173 DestroyMagickWand (image_wand
);
8177 if (ino
< 0 || ino
>= MagickGetNumberImages (image_wand
))
8179 image_error ("Invalid image number `%s' in image `%s'",
8181 DestroyMagickWand (image_wand
);
8185 if (MagickGetNumberImages (image_wand
) > 1)
8188 Fcons (make_number (MagickGetNumberImages (image_wand
)),
8191 /* If we have an animated image, get the new wand based on the
8193 if (MagickGetNumberImages (image_wand
) > 1)
8195 MagickWand
*super_wand
= image_wand
;
8196 image_wand
= imagemagick_compute_animated_image (super_wand
, ino
);
8198 image_wand
= super_wand
;
8200 DestroyMagickWand (super_wand
);
8203 /* Retrieve the frame's background color, for use later. */
8206 Lisp_Object specified_bg
;
8208 specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
8209 if (!STRINGP (specified_bg
)
8210 || !x_defined_color (f
, SSDATA (specified_bg
), &bgcolor
, 0))
8213 bgcolor
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
8214 x_query_color (f
, &bgcolor
);
8216 ns_query_color (FRAME_BACKGROUND_COLOR (f
), &bgcolor
, 1);
8220 bg_wand
= NewPixelWand ();
8221 PixelSetRed (bg_wand
, (double) bgcolor
.red
/ 65535);
8222 PixelSetGreen (bg_wand
, (double) bgcolor
.green
/ 65535);
8223 PixelSetBlue (bg_wand
, (double) bgcolor
.blue
/ 65535);
8226 compute_image_size (MagickGetImageWidth (image_wand
),
8227 MagickGetImageHeight (image_wand
),
8228 img
->spec
, &desired_width
, &desired_height
);
8230 if (desired_width
!= -1 && desired_height
!= -1)
8232 status
= MagickScaleImage (image_wand
, desired_width
, desired_height
);
8233 if (status
== MagickFalse
)
8235 image_error ("Imagemagick scale failed", Qnil
, Qnil
);
8236 imagemagick_error (image_wand
);
8237 goto imagemagick_error
;
8241 /* crop behaves similar to image slicing in Emacs but is more memory
8243 crop
= image_spec_value (img
->spec
, QCcrop
, NULL
);
8245 if (CONSP (crop
) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop
)))
8247 /* After some testing, it seems MagickCropImage is the fastest crop
8248 function in ImageMagick. This crop function seems to do less copying
8249 than the alternatives, but it still reads the entire image into memory
8250 before cropping, which is apparently difficult to avoid when using
8252 size_t crop_width
= XINT (XCAR (crop
));
8254 if (CONSP (crop
) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop
)))
8256 size_t crop_height
= XINT (XCAR (crop
));
8258 if (CONSP (crop
) && TYPE_RANGED_INTEGERP (ssize_t
, XCAR (crop
)))
8260 ssize_t crop_x
= XINT (XCAR (crop
));
8262 if (CONSP (crop
) && TYPE_RANGED_INTEGERP (ssize_t
, XCAR (crop
)))
8264 ssize_t crop_y
= XINT (XCAR (crop
));
8265 MagickCropImage (image_wand
, crop_width
, crop_height
,
8272 /* Furthermore :rotation. we need background color and angle for
8275 TODO background handling for rotation specified_bg =
8276 image_spec_value (img->spec, QCbackground, NULL); if (!STRINGP
8278 value
= image_spec_value (img
->spec
, QCrotation
, NULL
);
8281 rotation
= extract_float (value
);
8282 status
= MagickRotateImage (image_wand
, bg_wand
, rotation
);
8283 if (status
== MagickFalse
)
8285 image_error ("Imagemagick image rotate failed", Qnil
, Qnil
);
8286 imagemagick_error (image_wand
);
8287 goto imagemagick_error
;
8291 /* Set the canvas background color to the frame or specified
8292 background, and flatten the image. Note: as of ImageMagick
8293 6.6.0, SVG image transparency is not handled properly
8294 (e.g. etc/images/splash.svg shows a white background always). */
8296 MagickWand
*new_wand
;
8297 MagickSetImageBackgroundColor (image_wand
, bg_wand
);
8298 #ifdef HAVE_MAGICKMERGEIMAGELAYERS
8299 new_wand
= MagickMergeImageLayers (image_wand
, MergeLayer
);
8301 new_wand
= MagickFlattenImages (image_wand
);
8303 DestroyMagickWand (image_wand
);
8304 image_wand
= new_wand
;
8307 /* Finally we are done manipulating the image. Figure out the
8308 resulting width/height and transfer ownership to Emacs. */
8309 height
= MagickGetImageHeight (image_wand
);
8310 width
= MagickGetImageWidth (image_wand
);
8312 if (! (width
<= INT_MAX
&& height
<= INT_MAX
8313 && check_image_size (f
, width
, height
)))
8315 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
8316 goto imagemagick_error
;
8319 /* We can now get a valid pixel buffer from the imagemagick file, if all
8322 init_color_table ();
8324 #if defined (HAVE_MAGICKEXPORTIMAGEPIXELS) && ! defined (HAVE_NS)
8325 if (imagemagick_render_type
!= 0)
8327 /* Magicexportimage is normally faster than pixelpushing. This
8328 method is also well tested. Some aspects of this method are
8329 ad-hoc and needs to be more researched. */
8330 int imagedepth
= 24; /*MagickGetImageDepth(image_wand);*/
8331 const char *exportdepth
= imagedepth
<= 8 ? "I" : "BGRP"; /*"RGBP";*/
8332 /* Try to create a x pixmap to hold the imagemagick pixmap. */
8333 if (!image_create_x_image_and_pixmap (f
, img
, width
, height
, imagedepth
,
8336 #ifdef COLOR_TABLE_SUPPORT
8337 free_color_table ();
8339 image_error ("Imagemagick X bitmap allocation failure", Qnil
, Qnil
);
8340 goto imagemagick_error
;
8343 /* Oddly, the below code doesn't seem to work:*/
8344 /* switch(ximg->bitmap_unit){ */
8346 /* pixelwidth=CharPixel; */
8349 /* pixelwidth=ShortPixel; */
8352 /* pixelwidth=LongPixel; */
8356 Here im just guessing the format of the bitmap.
8357 happens to work fine for:
8360 seems about 3 times as fast as pixel pushing(not carefully measured)
8362 pixelwidth
= CharPixel
; /*??? TODO figure out*/
8363 MagickExportImagePixels (image_wand
, 0, 0, width
, height
,
8364 exportdepth
, pixelwidth
, ximg
->data
);
8367 #endif /* HAVE_MAGICKEXPORTIMAGEPIXELS */
8369 size_t image_height
;
8371 /* Try to create a x pixmap to hold the imagemagick pixmap. */
8372 if (!image_create_x_image_and_pixmap (f
, img
, width
, height
, 0,
8375 #ifdef COLOR_TABLE_SUPPORT
8376 free_color_table ();
8378 image_error ("Imagemagick X bitmap allocation failure", Qnil
, Qnil
);
8379 goto imagemagick_error
;
8382 /* Copy imagemagick image to x with primitive yet robust pixel
8383 pusher loop. This has been tested a lot with many different
8386 /* Copy pixels from the imagemagick image structure to the x image map. */
8387 iterator
= NewPixelIterator (image_wand
);
8390 #ifdef COLOR_TABLE_SUPPORT
8391 free_color_table ();
8393 x_destroy_x_image (ximg
);
8394 image_error ("Imagemagick pixel iterator creation failed",
8396 goto imagemagick_error
;
8399 image_height
= MagickGetImageHeight (image_wand
);
8400 for (y
= 0; y
< image_height
; y
++)
8402 pixels
= PixelGetNextIteratorRow (iterator
, &width
);
8405 for (x
= 0; x
< (long) width
; x
++)
8407 PixelGetMagickColor (pixels
[x
], &pixel
);
8408 XPutPixel (ximg
, x
, y
,
8409 lookup_rgb_color (f
,
8415 DestroyPixelIterator (iterator
);
8418 #ifdef COLOR_TABLE_SUPPORT
8419 /* Remember colors allocated for this image. */
8420 img
->colors
= colors_in_color_table (&img
->ncolors
);
8421 free_color_table ();
8422 #endif /* COLOR_TABLE_SUPPORT */
8425 img
->height
= height
;
8427 /* Put ximg into the image. */
8428 image_put_x_image (f
, img
, ximg
, 0);
8430 /* Final cleanup. image_wand should be the only resource left. */
8431 DestroyMagickWand (image_wand
);
8432 if (bg_wand
) DestroyPixelWand (bg_wand
);
8434 /* `MagickWandTerminus' terminates the imagemagick environment. */
8435 MagickWandTerminus ();
8440 DestroyMagickWand (image_wand
);
8441 if (bg_wand
) DestroyPixelWand (bg_wand
);
8443 MagickWandTerminus ();
8444 /* TODO more cleanup. */
8445 image_error ("Error parsing IMAGEMAGICK image `%s'", img
->spec
, Qnil
);
8450 /* Load IMAGEMAGICK image IMG for use on frame F. Value is true if
8451 successful. this function will go into the imagemagick_type structure, and
8452 the prototype thus needs to be compatible with that structure. */
8455 imagemagick_load (struct frame
*f
, struct image
*img
)
8458 Lisp_Object file_name
;
8460 /* If IMG->spec specifies a file name, create a non-file spec from it. */
8461 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
8462 if (STRINGP (file_name
))
8466 file
= x_find_image_file (file_name
);
8467 if (!STRINGP (file
))
8469 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
8472 success_p
= imagemagick_load_image (f
, img
, 0, 0, SSDATA (file
));
8474 /* Else its not a file, its a lisp object. Load the image from a
8475 lisp object rather than a file. */
8480 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8481 if (!STRINGP (data
))
8483 image_error ("Invalid image data `%s'", data
, Qnil
);
8486 success_p
= imagemagick_load_image (f
, img
, SDATA (data
),
8487 SBYTES (data
), NULL
);
8493 DEFUN ("imagemagick-types", Fimagemagick_types
, Simagemagick_types
, 0, 0, 0,
8494 doc
: /* Return a list of image types supported by ImageMagick.
8495 Each entry in this list is a symbol named after an ImageMagick format
8496 tag. See the ImageMagick manual for a list of ImageMagick formats and
8497 their descriptions (http://www.imagemagick.org/script/formats.php).
8498 You can also try the shell command: `identify -list format'.
8500 Note that ImageMagick recognizes many file-types that Emacs does not
8501 recognize as images, such as C. See `imagemagick-types-enable'
8502 and `imagemagick-types-inhibit'. */)
8505 Lisp_Object typelist
= Qnil
;
8510 Lisp_Object Qimagemagicktype
;
8512 GetExceptionInfo(&ex
);
8513 imtypes
= GetMagickList ("*", &numf
, &ex
);
8514 DestroyExceptionInfo(&ex
);
8516 for (i
= 0; i
< numf
; i
++)
8518 Qimagemagicktype
= intern (imtypes
[i
]);
8519 typelist
= Fcons (Qimagemagicktype
, typelist
);
8521 return Fnreverse (typelist
);
8524 #endif /* defined (HAVE_IMAGEMAGICK) */
8528 /***********************************************************************
8530 ***********************************************************************/
8532 #if defined (HAVE_RSVG)
8534 /* Function prototypes. */
8536 static bool svg_image_p (Lisp_Object object
);
8537 static bool svg_load (struct frame
*f
, struct image
*img
);
8539 static bool svg_load_image (struct frame
*, struct image
*,
8540 unsigned char *, ptrdiff_t);
8542 /* The symbol `svg' identifying images of this type. */
8544 static Lisp_Object Qsvg
;
8546 /* Indices of image specification fields in svg_format, below. */
8548 enum svg_keyword_index
8563 /* Vector of image_keyword structures describing the format
8564 of valid user-defined image specifications. */
8566 static const struct image_keyword svg_format
[SVG_LAST
] =
8568 {":type", IMAGE_SYMBOL_VALUE
, 1},
8569 {":data", IMAGE_STRING_VALUE
, 0},
8570 {":file", IMAGE_STRING_VALUE
, 0},
8571 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8572 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
8573 {":relief", IMAGE_INTEGER_VALUE
, 0},
8574 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8575 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8576 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8577 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8580 #if defined HAVE_NTGUI && defined WINDOWSNT
8581 static bool init_svg_functions (void);
8583 #define init_svg_functions NULL
8586 /* Structure describing the image type `svg'. Its the same type of
8587 structure defined for all image formats, handled by emacs image
8588 functions. See struct image_type in dispextern.h. */
8590 static struct image_type svg_type
=
8601 /* Return true if OBJECT is a valid SVG image specification. Do
8602 this by calling parse_image_spec and supplying the keywords that
8603 identify the SVG format. */
8606 svg_image_p (Lisp_Object object
)
8608 struct image_keyword fmt
[SVG_LAST
];
8609 memcpy (fmt
, svg_format
, sizeof fmt
);
8611 if (!parse_image_spec (object
, fmt
, SVG_LAST
, Qsvg
))
8614 /* Must specify either the :data or :file keyword. */
8615 return fmt
[SVG_FILE
].count
+ fmt
[SVG_DATA
].count
== 1;
8618 #include <librsvg/rsvg.h>
8622 /* SVG library functions. */
8623 DEF_IMGLIB_FN (RsvgHandle
*, rsvg_handle_new
, (void));
8624 DEF_IMGLIB_FN (void, rsvg_handle_get_dimensions
, (RsvgHandle
*, RsvgDimensionData
*));
8625 DEF_IMGLIB_FN (gboolean
, rsvg_handle_write
, (RsvgHandle
*, const guchar
*, gsize
, GError
**));
8626 DEF_IMGLIB_FN (gboolean
, rsvg_handle_close
, (RsvgHandle
*, GError
**));
8627 DEF_IMGLIB_FN (GdkPixbuf
*, rsvg_handle_get_pixbuf
, (RsvgHandle
*));
8628 DEF_IMGLIB_FN (void *, rsvg_handle_set_size_callback
, (RsvgHandle
*, RsvgSizeFunc
, gpointer
, GDestroyNotify
));
8630 DEF_IMGLIB_FN (int, gdk_pixbuf_get_width
, (const GdkPixbuf
*));
8631 DEF_IMGLIB_FN (int, gdk_pixbuf_get_height
, (const GdkPixbuf
*));
8632 DEF_IMGLIB_FN (guchar
*, gdk_pixbuf_get_pixels
, (const GdkPixbuf
*));
8633 DEF_IMGLIB_FN (int, gdk_pixbuf_get_rowstride
, (const GdkPixbuf
*));
8634 DEF_IMGLIB_FN (GdkColorspace
, gdk_pixbuf_get_colorspace
, (const GdkPixbuf
*));
8635 DEF_IMGLIB_FN (int, gdk_pixbuf_get_n_channels
, (const GdkPixbuf
*));
8636 DEF_IMGLIB_FN (gboolean
, gdk_pixbuf_get_has_alpha
, (const GdkPixbuf
*));
8637 DEF_IMGLIB_FN (int, gdk_pixbuf_get_bits_per_sample
, (const GdkPixbuf
*));
8639 #if ! GLIB_CHECK_VERSION (2, 36, 0)
8640 DEF_IMGLIB_FN (void, g_type_init
, (void));
8642 DEF_IMGLIB_FN (void, g_object_unref
, (gpointer
));
8643 DEF_IMGLIB_FN (void, g_error_free
, (GError
*));
8645 Lisp_Object Qgdk_pixbuf
, Qglib
, Qgobject
;
8648 init_svg_functions (void)
8650 HMODULE library
, gdklib
, glib
, gobject
;
8652 if (!(glib
= w32_delayed_load (Qglib
))
8653 || !(gobject
= w32_delayed_load (Qgobject
))
8654 || !(gdklib
= w32_delayed_load (Qgdk_pixbuf
))
8655 || !(library
= w32_delayed_load (Qsvg
)))
8658 LOAD_IMGLIB_FN (library
, rsvg_handle_new
);
8659 LOAD_IMGLIB_FN (library
, rsvg_handle_get_dimensions
);
8660 LOAD_IMGLIB_FN (library
, rsvg_handle_write
);
8661 LOAD_IMGLIB_FN (library
, rsvg_handle_close
);
8662 LOAD_IMGLIB_FN (library
, rsvg_handle_get_pixbuf
);
8664 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_width
);
8665 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_height
);
8666 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_pixels
);
8667 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_rowstride
);
8668 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_colorspace
);
8669 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_n_channels
);
8670 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_has_alpha
);
8671 LOAD_IMGLIB_FN (gdklib
, gdk_pixbuf_get_bits_per_sample
);
8673 #if ! GLIB_CHECK_VERSION (2, 36, 0)
8674 LOAD_IMGLIB_FN (gobject
, g_type_init
);
8676 LOAD_IMGLIB_FN (gobject
, g_object_unref
);
8677 LOAD_IMGLIB_FN (glib
, g_error_free
);
8683 /* The following aliases for library functions allow dynamic loading
8684 to be used on some platforms. */
8685 #define fn_rsvg_handle_new rsvg_handle_new
8686 #define fn_rsvg_handle_get_dimensions rsvg_handle_get_dimensions
8687 #define fn_rsvg_handle_write rsvg_handle_write
8688 #define fn_rsvg_handle_close rsvg_handle_close
8689 #define fn_rsvg_handle_get_pixbuf rsvg_handle_get_pixbuf
8691 #define fn_gdk_pixbuf_get_width gdk_pixbuf_get_width
8692 #define fn_gdk_pixbuf_get_height gdk_pixbuf_get_height
8693 #define fn_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels
8694 #define fn_gdk_pixbuf_get_rowstride gdk_pixbuf_get_rowstride
8695 #define fn_gdk_pixbuf_get_colorspace gdk_pixbuf_get_colorspace
8696 #define fn_gdk_pixbuf_get_n_channels gdk_pixbuf_get_n_channels
8697 #define fn_gdk_pixbuf_get_has_alpha gdk_pixbuf_get_has_alpha
8698 #define fn_gdk_pixbuf_get_bits_per_sample gdk_pixbuf_get_bits_per_sample
8700 #if ! GLIB_CHECK_VERSION (2, 36, 0)
8701 #define fn_g_type_init g_type_init
8703 #define fn_g_object_unref g_object_unref
8704 #define fn_g_error_free g_error_free
8705 #endif /* !WINDOWSNT */
8707 /* Load SVG image IMG for use on frame F. Value is true if
8711 svg_load (struct frame
*f
, struct image
*img
)
8714 Lisp_Object file_name
;
8716 /* If IMG->spec specifies a file name, create a non-file spec from it. */
8717 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
8718 if (STRINGP (file_name
))
8721 unsigned char *contents
;
8724 file
= x_find_image_file (file_name
);
8725 if (!STRINGP (file
))
8727 image_error ("Cannot find image file `%s'", file_name
, Qnil
);
8731 /* Read the entire file into memory. */
8732 contents
= slurp_file (SSDATA (file
), &size
);
8733 if (contents
== NULL
)
8735 image_error ("Error loading SVG image `%s'", img
->spec
, Qnil
);
8738 /* If the file was slurped into memory properly, parse it. */
8739 success_p
= svg_load_image (f
, img
, contents
, size
);
8742 /* Else its not a file, its a lisp object. Load the image from a
8743 lisp object rather than a file. */
8748 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8749 if (!STRINGP (data
))
8751 image_error ("Invalid image data `%s'", data
, Qnil
);
8754 success_p
= svg_load_image (f
, img
, SDATA (data
), SBYTES (data
));
8760 /* svg_load_image is a helper function for svg_load, which does the
8761 actual loading given contents and size, apart from frame and image
8762 structures, passed from svg_load.
8764 Uses librsvg to do most of the image processing.
8766 Returns true when successful. */
8768 svg_load_image (struct frame
*f
, /* Pointer to emacs frame structure. */
8769 struct image
*img
, /* Pointer to emacs image structure. */
8770 unsigned char *contents
, /* String containing the SVG XML data to be parsed. */
8771 ptrdiff_t size
) /* Size of data in bytes. */
8773 RsvgHandle
*rsvg_handle
;
8774 RsvgDimensionData dimension_data
;
8779 const guint8
*pixels
;
8782 Lisp_Object specified_bg
;
8787 #if ! GLIB_CHECK_VERSION (2, 36, 0)
8788 /* g_type_init is a glib function that must be called prior to
8789 using gnome type library functions (obsolete since 2.36.0). */
8793 /* Make a handle to a new rsvg object. */
8794 rsvg_handle
= fn_rsvg_handle_new ();
8796 /* Parse the contents argument and fill in the rsvg_handle. */
8797 fn_rsvg_handle_write (rsvg_handle
, contents
, size
, &err
);
8798 if (err
) goto rsvg_error
;
8800 /* The parsing is complete, rsvg_handle is ready to used, close it
8801 for further writes. */
8802 fn_rsvg_handle_close (rsvg_handle
, &err
);
8803 if (err
) goto rsvg_error
;
8805 fn_rsvg_handle_get_dimensions (rsvg_handle
, &dimension_data
);
8806 if (! check_image_size (f
, dimension_data
.width
, dimension_data
.height
))
8808 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
8812 /* We can now get a valid pixel buffer from the svg file, if all
8814 pixbuf
= fn_rsvg_handle_get_pixbuf (rsvg_handle
);
8815 if (!pixbuf
) goto rsvg_error
;
8816 fn_g_object_unref (rsvg_handle
);
8818 /* Extract some meta data from the svg handle. */
8819 width
= fn_gdk_pixbuf_get_width (pixbuf
);
8820 height
= fn_gdk_pixbuf_get_height (pixbuf
);
8821 pixels
= fn_gdk_pixbuf_get_pixels (pixbuf
);
8822 rowstride
= fn_gdk_pixbuf_get_rowstride (pixbuf
);
8824 /* Validate the svg meta data. */
8825 eassert (fn_gdk_pixbuf_get_colorspace (pixbuf
) == GDK_COLORSPACE_RGB
);
8826 eassert (fn_gdk_pixbuf_get_n_channels (pixbuf
) == 4);
8827 eassert (fn_gdk_pixbuf_get_has_alpha (pixbuf
));
8828 eassert (fn_gdk_pixbuf_get_bits_per_sample (pixbuf
) == 8);
8830 /* Try to create a x pixmap to hold the svg pixmap. */
8831 if (!image_create_x_image_and_pixmap (f
, img
, width
, height
, 0, &ximg
, 0))
8833 fn_g_object_unref (pixbuf
);
8837 init_color_table ();
8839 /* Handle alpha channel by combining the image with a background
8841 specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
8842 if (!STRINGP (specified_bg
)
8843 || !x_defined_color (f
, SSDATA (specified_bg
), &background
, 0))
8846 background
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
8847 x_query_color (f
, &background
);
8849 ns_query_color (FRAME_BACKGROUND_COLOR (f
), &background
, 1);
8853 /* SVG pixmaps specify transparency in the last byte, so right
8854 shift 8 bits to get rid of it, since emacs doesn't support
8856 background
.red
>>= 8;
8857 background
.green
>>= 8;
8858 background
.blue
>>= 8;
8860 /* This loop handles opacity values, since Emacs assumes
8861 non-transparent images. Each pixel must be "flattened" by
8862 calculating the resulting color, given the transparency of the
8863 pixel, and the image background color. */
8864 for (y
= 0; y
< height
; ++y
)
8866 for (x
= 0; x
< width
; ++x
)
8876 opacity
= *pixels
++;
8878 red
= ((red
* opacity
)
8879 + (background
.red
* ((1 << 8) - opacity
)));
8880 green
= ((green
* opacity
)
8881 + (background
.green
* ((1 << 8) - opacity
)));
8882 blue
= ((blue
* opacity
)
8883 + (background
.blue
* ((1 << 8) - opacity
)));
8885 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, red
, green
, blue
));
8888 pixels
+= rowstride
- 4 * width
;
8891 #ifdef COLOR_TABLE_SUPPORT
8892 /* Remember colors allocated for this image. */
8893 img
->colors
= colors_in_color_table (&img
->ncolors
);
8894 free_color_table ();
8895 #endif /* COLOR_TABLE_SUPPORT */
8897 fn_g_object_unref (pixbuf
);
8900 img
->height
= height
;
8902 /* Maybe fill in the background field while we have ximg handy.
8903 Casting avoids a GCC warning. */
8904 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
8906 /* Put ximg into the image. */
8907 image_put_x_image (f
, img
, ximg
, 0);
8912 fn_g_object_unref (rsvg_handle
);
8913 /* FIXME: Use error->message so the user knows what is the actual
8914 problem with the image. */
8915 image_error ("Error parsing SVG image `%s'", img
->spec
, Qnil
);
8916 fn_g_error_free (err
);
8920 #endif /* defined (HAVE_RSVG) */
8925 /***********************************************************************
8927 ***********************************************************************/
8929 #ifdef HAVE_X_WINDOWS
8930 #define HAVE_GHOSTSCRIPT 1
8931 #endif /* HAVE_X_WINDOWS */
8933 #ifdef HAVE_GHOSTSCRIPT
8935 static bool gs_image_p (Lisp_Object object
);
8936 static bool gs_load (struct frame
*f
, struct image
*img
);
8937 static void gs_clear_image (struct frame
*f
, struct image
*img
);
8939 /* Keyword symbols. */
8941 static Lisp_Object QCloader
, QCbounding_box
, QCpt_width
, QCpt_height
;
8943 /* Indices of image specification fields in gs_format, below. */
8945 enum gs_keyword_index
8963 /* Vector of image_keyword structures describing the format
8964 of valid user-defined image specifications. */
8966 static const struct image_keyword gs_format
[GS_LAST
] =
8968 {":type", IMAGE_SYMBOL_VALUE
, 1},
8969 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8970 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
8971 {":file", IMAGE_STRING_VALUE
, 1},
8972 {":loader", IMAGE_FUNCTION_VALUE
, 0},
8973 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
8974 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8975 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
8976 {":relief", IMAGE_INTEGER_VALUE
, 0},
8977 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8978 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8979 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8980 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8983 /* Structure describing the image type `ghostscript'. */
8985 static struct image_type gs_type
=
8996 /* Free X resources of Ghostscript image IMG which is used on frame F. */
8999 gs_clear_image (struct frame
*f
, struct image
*img
)
9001 x_clear_image (f
, img
);
9005 /* Return true if OBJECT is a valid Ghostscript image
9009 gs_image_p (Lisp_Object object
)
9011 struct image_keyword fmt
[GS_LAST
];
9015 memcpy (fmt
, gs_format
, sizeof fmt
);
9017 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
9020 /* Bounding box must be a list or vector containing 4 integers. */
9021 tem
= fmt
[GS_BOUNDING_BOX
].value
;
9024 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
9025 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
9030 else if (VECTORP (tem
))
9032 if (ASIZE (tem
) != 4)
9034 for (i
= 0; i
< 4; ++i
)
9035 if (!INTEGERP (AREF (tem
, i
)))
9045 /* Load Ghostscript image IMG for use on frame F. Value is true
9049 gs_load (struct frame
*f
, struct image
*img
)
9051 uprintmax_t printnum1
, printnum2
;
9052 char buffer
[sizeof " " + INT_STRLEN_BOUND (printmax_t
)];
9053 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
9055 double in_width
, in_height
;
9056 Lisp_Object pixel_colors
= Qnil
;
9058 /* Compute pixel size of pixmap needed from the given size in the
9059 image specification. Sizes in the specification are in pt. 1 pt
9060 = 1/72 in, xdpi and ydpi are stored in the frame's X display
9062 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
9063 in_width
= INTEGERP (pt_width
) ? XFASTINT (pt_width
) / 72.0 : 0;
9064 in_width
*= FRAME_RES_X (f
);
9065 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
9066 in_height
= INTEGERP (pt_height
) ? XFASTINT (pt_height
) / 72.0 : 0;
9067 in_height
*= FRAME_RES_Y (f
);
9069 if (! (in_width
<= INT_MAX
&& in_height
<= INT_MAX
9070 && check_image_size (f
, in_width
, in_height
)))
9072 image_error ("Invalid image size (see `max-image-size')", Qnil
, Qnil
);
9075 img
->width
= in_width
;
9076 img
->height
= in_height
;
9078 /* Create the pixmap. */
9079 eassert (img
->pixmap
== NO_PIXMAP
);
9081 if (x_check_image_size (0, img
->width
, img
->height
))
9083 /* Only W32 version did BLOCK_INPUT here. ++kfs */
9085 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9086 img
->width
, img
->height
,
9087 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
9093 image_error ("Unable to create pixmap for `%s'", img
->spec
, Qnil
);
9097 /* Call the loader to fill the pixmap. It returns a process object
9098 if successful. We do not record_unwind_protect here because
9099 other places in redisplay like calling window scroll functions
9100 don't either. Let the Lisp loader use `unwind-protect' instead. */
9101 printnum1
= FRAME_X_WINDOW (f
);
9102 printnum2
= img
->pixmap
;
9103 window_and_pixmap_id
9104 = make_formatted_string (buffer
, "%"pMu
" %"pMu
, printnum1
, printnum2
);
9106 printnum1
= FRAME_FOREGROUND_PIXEL (f
);
9107 printnum2
= FRAME_BACKGROUND_PIXEL (f
);
9109 = make_formatted_string (buffer
, "%"pMu
" %"pMu
, printnum1
, printnum2
);
9111 XSETFRAME (frame
, f
);
9112 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
9114 loader
= intern ("gs-load-image");
9116 img
->lisp_data
= call6 (loader
, frame
, img
->spec
,
9117 make_number (img
->width
),
9118 make_number (img
->height
),
9119 window_and_pixmap_id
,
9121 return PROCESSP (img
->lisp_data
);
9125 /* Kill the Ghostscript process that was started to fill PIXMAP on
9126 frame F. Called from XTread_socket when receiving an event
9127 telling Emacs that Ghostscript has finished drawing. */
9130 x_kill_gs_process (Pixmap pixmap
, struct frame
*f
)
9132 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
9137 /* Find the image containing PIXMAP. */
9138 for (i
= 0; i
< c
->used
; ++i
)
9139 if (c
->images
[i
]->pixmap
== pixmap
)
9142 /* Should someone in between have cleared the image cache, for
9143 instance, give up. */
9147 /* Kill the GS process. We should have found PIXMAP in the image
9148 cache and its image should contain a process object. */
9150 eassert (PROCESSP (img
->lisp_data
));
9151 Fkill_process (img
->lisp_data
, Qnil
);
9152 img
->lisp_data
= Qnil
;
9154 #if defined (HAVE_X_WINDOWS)
9156 /* On displays with a mutable colormap, figure out the colors
9157 allocated for the image by looking at the pixels of an XImage for
9159 class = FRAME_X_VISUAL (f
)->class;
9160 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
9166 /* Try to get an XImage for img->pixmep. */
9167 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
9168 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
9173 /* Initialize the color table. */
9174 init_color_table ();
9176 /* For each pixel of the image, look its color up in the
9177 color table. After having done so, the color table will
9178 contain an entry for each color used by the image. */
9179 for (y
= 0; y
< img
->height
; ++y
)
9180 for (x
= 0; x
< img
->width
; ++x
)
9182 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
9183 lookup_pixel_color (f
, pixel
);
9186 /* Record colors in the image. Free color table and XImage. */
9187 #ifdef COLOR_TABLE_SUPPORT
9188 img
->colors
= colors_in_color_table (&img
->ncolors
);
9189 free_color_table ();
9191 XDestroyImage (ximg
);
9193 #if 0 /* This doesn't seem to be the case. If we free the colors
9194 here, we get a BadAccess later in x_clear_image when
9195 freeing the colors. */
9196 /* We have allocated colors once, but Ghostscript has also
9197 allocated colors on behalf of us. So, to get the
9198 reference counts right, free them once. */
9200 x_free_colors (f
, img
->colors
, img
->ncolors
);
9204 image_error ("Cannot get X image of `%s'; colors will not be freed",
9209 #endif /* HAVE_X_WINDOWS */
9211 /* Now that we have the pixmap, compute mask and transform the
9212 image if requested. */
9214 postprocess_image (f
, img
);
9218 #endif /* HAVE_GHOSTSCRIPT */
9221 /***********************************************************************
9223 ***********************************************************************/
9227 DEFUN ("imagep", Fimagep
, Simagep
, 1, 1, 0,
9228 doc
: /* Value is non-nil if SPEC is a valid image specification. */)
9231 return valid_image_p (spec
) ? Qt
: Qnil
;
9235 DEFUN ("lookup-image", Flookup_image
, Slookup_image
, 1, 1, 0, "")
9240 if (valid_image_p (spec
))
9241 id
= lookup_image (SELECTED_FRAME (), spec
);
9244 return make_number (id
);
9247 #endif /* GLYPH_DEBUG */
9250 /***********************************************************************
9252 ***********************************************************************/
9254 DEFUN ("init-image-library", Finit_image_library
, Sinit_image_library
, 1, 1, 0,
9255 doc
: /* Initialize image library implementing image type TYPE.
9256 Return non-nil if TYPE is a supported image type.
9258 If image libraries are loaded dynamically (currently only the case on
9259 MS-Windows), load the library for TYPE if it is not yet loaded, using
9260 the library file(s) specified by `dynamic-library-alist'. */)
9263 return lookup_image_type (type
) ? Qt
: Qnil
;
9266 /* Look up image type TYPE, and return a pointer to its image_type
9267 structure. Return 0 if TYPE is not a known image type. */
9269 static struct image_type
*
9270 lookup_image_type (Lisp_Object type
)
9272 /* Types pbm and xbm are built-in and always available. */
9273 if (EQ (type
, Qpbm
))
9274 return define_image_type (&pbm_type
);
9276 if (EQ (type
, Qxbm
))
9277 return define_image_type (&xbm_type
);
9279 #if defined (HAVE_XPM) || defined (HAVE_NS)
9280 if (EQ (type
, Qxpm
))
9281 return define_image_type (&xpm_type
);
9284 #if defined (HAVE_JPEG) || defined (HAVE_NS)
9285 if (EQ (type
, Qjpeg
))
9286 return define_image_type (&jpeg_type
);
9289 #if defined (HAVE_TIFF) || defined (HAVE_NS)
9290 if (EQ (type
, Qtiff
))
9291 return define_image_type (&tiff_type
);
9294 #if defined (HAVE_GIF) || defined (HAVE_NS)
9295 if (EQ (type
, Qgif
))
9296 return define_image_type (&gif_type
);
9299 #if defined (HAVE_PNG) || defined (HAVE_NS)
9300 if (EQ (type
, Qpng
))
9301 return define_image_type (&png_type
);
9304 #if defined (HAVE_RSVG)
9305 if (EQ (type
, Qsvg
))
9306 return define_image_type (&svg_type
);
9309 #if defined (HAVE_IMAGEMAGICK)
9310 if (EQ (type
, Qimagemagick
))
9311 return define_image_type (&imagemagick_type
);
9314 #ifdef HAVE_GHOSTSCRIPT
9315 if (EQ (type
, Qpostscript
))
9316 return define_image_type (&gs_type
);
9322 /* Reset image_types before dumping.
9323 Called from Fdump_emacs. */
9326 reset_image_types (void)
9330 struct image_type
*next
= image_types
->next
;
9331 xfree (image_types
);
9337 syms_of_image (void)
9339 /* Initialize this only once; it will be reset before dumping. */
9342 /* Must be defined now because we're going to update it below, while
9343 defining the supported image types. */
9344 DEFVAR_LISP ("image-types", Vimage_types
,
9345 doc
: /* List of potentially supported image types.
9346 Each element of the list is a symbol for an image type, like 'jpeg or 'png.
9347 To check whether it is really supported, use `image-type-available-p'. */);
9348 Vimage_types
= Qnil
;
9350 DEFVAR_LISP ("max-image-size", Vmax_image_size
,
9351 doc
: /* Maximum size of images.
9352 Emacs will not load an image into memory if its pixel width or
9353 pixel height exceeds this limit.
9355 If the value is an integer, it directly specifies the maximum
9356 image height and width, measured in pixels. If it is a floating
9357 point number, it specifies the maximum image height and width
9358 as a ratio to the frame height and width. If the value is
9359 non-numeric, there is no explicit limit on the size of images. */);
9360 Vmax_image_size
= make_float (MAX_IMAGE_SIZE
);
9362 DEFSYM (Qcount
, "count");
9363 DEFSYM (Qextension_data
, "extension-data");
9364 DEFSYM (Qdelay
, "delay");
9366 DEFSYM (QCascent
, ":ascent");
9367 DEFSYM (QCmargin
, ":margin");
9368 DEFSYM (QCrelief
, ":relief");
9369 DEFSYM (QCconversion
, ":conversion");
9370 DEFSYM (QCcolor_symbols
, ":color-symbols");
9371 DEFSYM (QCheuristic_mask
, ":heuristic-mask");
9372 DEFSYM (QCindex
, ":index");
9373 DEFSYM (QCgeometry
, ":geometry");
9374 DEFSYM (QCcrop
, ":crop");
9375 DEFSYM (QCrotation
, ":rotation");
9376 DEFSYM (QCmatrix
, ":matrix");
9377 DEFSYM (QCcolor_adjustment
, ":color-adjustment");
9378 DEFSYM (QCmask
, ":mask");
9380 DEFSYM (Qlaplace
, "laplace");
9381 DEFSYM (Qemboss
, "emboss");
9382 DEFSYM (Qedge_detection
, "edge-detection");
9383 DEFSYM (Qheuristic
, "heuristic");
9385 DEFSYM (Qpostscript
, "postscript");
9386 DEFSYM (QCmax_width
, ":max-width");
9387 DEFSYM (QCmax_height
, ":max-height");
9388 #ifdef HAVE_GHOSTSCRIPT
9389 ADD_IMAGE_TYPE (Qpostscript
);
9390 DEFSYM (QCloader
, ":loader");
9391 DEFSYM (QCbounding_box
, ":bounding-box");
9392 DEFSYM (QCpt_width
, ":pt-width");
9393 DEFSYM (QCpt_height
, ":pt-height");
9394 #endif /* HAVE_GHOSTSCRIPT */
9397 DEFSYM (Qlibpng_version
, "libpng-version");
9398 Fset (Qlibpng_version
,
9400 make_number (PNG_LIBPNG_VER
)
9405 DEFSYM (Qlibgif_version
, "libgif-version");
9406 Fset (Qlibgif_version
,
9408 make_number (GIFLIB_MAJOR
* 10000
9409 + GIFLIB_MINOR
* 100
9417 DEFSYM (Qpbm
, "pbm");
9418 ADD_IMAGE_TYPE (Qpbm
);
9420 DEFSYM (Qxbm
, "xbm");
9421 ADD_IMAGE_TYPE (Qxbm
);
9423 #if defined (HAVE_XPM) || defined (HAVE_NS)
9424 DEFSYM (Qxpm
, "xpm");
9425 ADD_IMAGE_TYPE (Qxpm
);
9428 #if defined (HAVE_JPEG) || defined (HAVE_NS)
9429 DEFSYM (Qjpeg
, "jpeg");
9430 ADD_IMAGE_TYPE (Qjpeg
);
9433 #if defined (HAVE_TIFF) || defined (HAVE_NS)
9434 DEFSYM (Qtiff
, "tiff");
9435 ADD_IMAGE_TYPE (Qtiff
);
9438 #if defined (HAVE_GIF) || defined (HAVE_NS)
9439 DEFSYM (Qgif
, "gif");
9440 ADD_IMAGE_TYPE (Qgif
);
9443 #if defined (HAVE_PNG) || defined (HAVE_NS)
9444 DEFSYM (Qpng
, "png");
9445 ADD_IMAGE_TYPE (Qpng
);
9448 #if defined (HAVE_IMAGEMAGICK)
9449 DEFSYM (Qimagemagick
, "imagemagick");
9450 ADD_IMAGE_TYPE (Qimagemagick
);
9453 #if defined (HAVE_RSVG)
9454 DEFSYM (Qsvg
, "svg");
9455 ADD_IMAGE_TYPE (Qsvg
);
9457 /* Other libraries used directly by svg code. */
9458 DEFSYM (Qgdk_pixbuf
, "gdk-pixbuf");
9459 DEFSYM (Qglib
, "glib");
9460 DEFSYM (Qgobject
, "gobject");
9461 #endif /* HAVE_NTGUI */
9462 #endif /* HAVE_RSVG */
9464 defsubr (&Sinit_image_library
);
9465 #ifdef HAVE_IMAGEMAGICK
9466 defsubr (&Simagemagick_types
);
9468 defsubr (&Sclear_image_cache
);
9469 defsubr (&Simage_flush
);
9470 defsubr (&Simage_size
);
9471 defsubr (&Simage_mask_p
);
9472 defsubr (&Simage_metadata
);
9476 defsubr (&Slookup_image
);
9479 DEFVAR_BOOL ("cross-disabled-images", cross_disabled_images
,
9480 doc
: /* Non-nil means always draw a cross over disabled images.
9481 Disabled images are those having a `:conversion disabled' property.
9482 A cross is always drawn on black & white displays. */);
9483 cross_disabled_images
= 0;
9485 DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path
,
9486 doc
: /* List of directories to search for window system bitmap files. */);
9487 Vx_bitmap_file_path
= decode_env_path (0, PATH_BITMAPS
);
9489 DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay
,
9490 doc
: /* Maximum time after which images are removed from the cache.
9491 When an image has not been displayed this many seconds, Emacs
9492 automatically removes it from the image cache. If the cache contains
9493 a large number of images, the actual eviction time may be shorter.
9494 The value can also be nil, meaning the cache is never cleared.
9496 The function `clear-image-cache' disregards this variable. */);
9497 Vimage_cache_eviction_delay
= make_number (300);
9498 #ifdef HAVE_IMAGEMAGICK
9499 DEFVAR_INT ("imagemagick-render-type", imagemagick_render_type
,
9500 doc
: /* Integer indicating which ImageMagick rendering method to use.
9502 0 -- the default method (pixel pushing)
9503 1 -- a newer method ("MagickExportImagePixels") that may perform
9504 better (speed etc) in some cases, but has not been as thoroughly
9505 tested with Emacs as the default method. This method requires
9506 ImageMagick version 6.4.6 (approximately) or later.
9508 /* MagickExportImagePixels is in 6.4.6-9, but not 6.4.4-10. */
9509 imagemagick_render_type
= 0;