1 /* Functions for image support on window system.
3 Copyright (C) 1989, 1992-2016 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 (at
10 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/>. */
26 /* Include this before including <setjmp.h> to work around bugs with
27 older libpng; see Bug#17429. */
28 #if defined HAVE_PNG && !defined HAVE_NS
39 #include "dispextern.h"
40 #include "blockinput.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 typedef struct x_bitmap_record Bitmap_Record
;
61 #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
62 #define NO_PIXMAP None
64 #define PIX_MASK_RETAIN 0
65 #define PIX_MASK_DRAW 1
66 #endif /* HAVE_X_WINDOWS */
70 /* We need (or want) w32.h only when we're _not_ compiling for Cygwin. */
75 typedef struct w32_bitmap_record Bitmap_Record
;
76 #define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y)
79 #define PIX_MASK_RETAIN 0
80 #define PIX_MASK_DRAW 1
82 #define x_defined_color w32_defined_color
83 #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
85 #endif /* HAVE_NTGUI */
88 typedef struct ns_bitmap_record Bitmap_Record
;
90 #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
93 #define PIX_MASK_RETAIN 0
94 #define PIX_MASK_DRAW 1
96 #define x_defined_color(f, name, color_def, alloc) \
97 ns_defined_color (f, name, color_def, alloc, 0)
98 #define DefaultDepthOfScreen(screen) x_display_list->n_planes
101 #if (defined HAVE_X_WINDOWS \
102 && ! (defined HAVE_NTGUI || defined USE_CAIRO || defined HAVE_NS))
103 /* W32_TODO : Color tables on W32. */
104 # define COLOR_TABLE_SUPPORT 1
107 static void x_disable_image (struct frame
*, struct image
*);
108 static void x_edge_detection (struct frame
*, struct image
*, Lisp_Object
,
111 static void init_color_table (void);
112 static unsigned long lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
);
113 #ifdef COLOR_TABLE_SUPPORT
114 static void free_color_table (void);
115 static unsigned long *colors_in_color_table (int *n
);
118 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
119 id, which is just an int that this section returns. Bitmaps are
120 reference counted so they can be shared among frames.
122 Bitmap indices are guaranteed to be > 0, so a negative number can
123 be used to indicate no bitmap.
125 If you use x_create_bitmap_from_data, then you must keep track of
126 the bitmaps yourself. That is, creating a bitmap from the same
127 data more than once will not be caught. */
130 /* Use with images created by ns_image_for_XPM. */
132 XGetPixel (XImagePtr ximage
, int x
, int y
)
134 return ns_get_pixel (ximage
, x
, y
);
137 /* Use with images created by ns_image_for_XPM; alpha set to 1;
138 pixel is assumed to be in RGB form. */
140 XPutPixel (XImagePtr ximage
, int x
, int y
, unsigned long pixel
)
142 ns_put_pixel (ximage
, x
, y
, pixel
);
147 /* Functions to access the contents of a bitmap, given an id. */
149 #ifdef HAVE_X_WINDOWS
151 x_bitmap_height (struct frame
*f
, ptrdiff_t id
)
153 return FRAME_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
157 x_bitmap_width (struct frame
*f
, ptrdiff_t id
)
159 return FRAME_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
163 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
165 x_bitmap_pixmap (struct frame
*f
, ptrdiff_t id
)
167 /* HAVE_NTGUI needs the explicit cast here. */
168 return (ptrdiff_t) FRAME_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
172 #ifdef HAVE_X_WINDOWS
174 x_bitmap_mask (struct frame
*f
, ptrdiff_t id
)
176 return FRAME_DISPLAY_INFO (f
)->bitmaps
[id
- 1].mask
;
180 /* Allocate a new bitmap record. Returns index of new record. */
183 x_allocate_bitmap_record (struct frame
*f
)
185 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
188 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
189 return ++dpyinfo
->bitmaps_last
;
191 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
192 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
196 xpalloc (dpyinfo
->bitmaps
, &dpyinfo
->bitmaps_size
,
197 10, -1, sizeof *dpyinfo
->bitmaps
);
198 return ++dpyinfo
->bitmaps_last
;
201 /* Add one reference to the reference count of the bitmap with id ID. */
204 x_reference_bitmap (struct frame
*f
, ptrdiff_t id
)
206 ++FRAME_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
209 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
212 x_create_bitmap_from_data (struct frame
*f
, char *bits
, unsigned int width
, unsigned int height
)
214 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
217 #ifdef HAVE_X_WINDOWS
219 bitmap
= XCreateBitmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
220 bits
, width
, height
);
223 #endif /* HAVE_X_WINDOWS */
227 bitmap
= CreateBitmap (width
, height
,
228 FRAME_DISPLAY_INFO (XFRAME (frame
))->n_planes
,
229 FRAME_DISPLAY_INFO (XFRAME (frame
))->n_cbits
,
233 #endif /* HAVE_NTGUI */
236 void *bitmap
= ns_image_from_XBM (bits
, width
, height
, 0, 0);
241 id
= x_allocate_bitmap_record (f
);
244 dpyinfo
->bitmaps
[id
- 1].img
= bitmap
;
245 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
248 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
249 dpyinfo
->bitmaps
[id
- 1].height
= height
;
250 dpyinfo
->bitmaps
[id
- 1].width
= width
;
251 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
253 #ifdef HAVE_X_WINDOWS
254 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
255 dpyinfo
->bitmaps
[id
- 1].have_mask
= false;
256 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
257 #endif /* HAVE_X_WINDOWS */
260 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
261 dpyinfo
->bitmaps
[id
- 1].hinst
= NULL
;
262 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
263 #endif /* HAVE_NTGUI */
268 /* Create bitmap from file FILE for frame F. */
271 x_create_bitmap_from_file (struct frame
*f
, Lisp_Object file
)
273 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
276 return -1; /* W32_TODO : bitmap support */
277 #endif /* HAVE_NTGUI */
281 void *bitmap
= ns_image_from_file (file
);
287 id
= x_allocate_bitmap_record (f
);
288 dpyinfo
->bitmaps
[id
- 1].img
= bitmap
;
289 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
290 dpyinfo
->bitmaps
[id
- 1].file
= xlispstrdup (file
);
291 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
292 dpyinfo
->bitmaps
[id
- 1].height
= ns_image_width (bitmap
);
293 dpyinfo
->bitmaps
[id
- 1].width
= ns_image_height (bitmap
);
297 #ifdef HAVE_X_WINDOWS
298 unsigned int width
, height
;
300 int xhot
, yhot
, result
;
305 /* Look for an existing bitmap with the same name. */
306 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
308 if (dpyinfo
->bitmaps
[id
].refcount
309 && dpyinfo
->bitmaps
[id
].file
310 && !strcmp (dpyinfo
->bitmaps
[id
].file
, SSDATA (file
)))
312 ++dpyinfo
->bitmaps
[id
].refcount
;
317 /* Search bitmap-file-path for the file, if appropriate. */
318 if (openp (Vx_bitmap_file_path
, file
, Qnil
, &found
,
319 make_number (R_OK
), false)
323 filename
= SSDATA (found
);
325 result
= XReadBitmapFile (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
326 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
327 if (result
!= BitmapSuccess
)
330 id
= x_allocate_bitmap_record (f
);
331 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
332 dpyinfo
->bitmaps
[id
- 1].have_mask
= false;
333 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
334 dpyinfo
->bitmaps
[id
- 1].file
= xlispstrdup (file
);
335 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
336 dpyinfo
->bitmaps
[id
- 1].height
= height
;
337 dpyinfo
->bitmaps
[id
- 1].width
= width
;
340 #endif /* HAVE_X_WINDOWS */
346 free_bitmap_record (Display_Info
*dpyinfo
, Bitmap_Record
*bm
)
348 #ifdef HAVE_X_WINDOWS
349 XFreePixmap (dpyinfo
->display
, bm
->pixmap
);
351 XFreePixmap (dpyinfo
->display
, bm
->mask
);
352 #endif /* HAVE_X_WINDOWS */
355 DeleteObject (bm
->pixmap
);
356 #endif /* HAVE_NTGUI */
359 ns_release_object (bm
->img
);
369 /* Remove reference to bitmap with id number ID. */
372 x_destroy_bitmap (struct frame
*f
, ptrdiff_t id
)
374 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
378 Bitmap_Record
*bm
= &dpyinfo
->bitmaps
[id
- 1];
380 if (--bm
->refcount
== 0)
383 free_bitmap_record (dpyinfo
, bm
);
389 /* Free all the bitmaps for the display specified by DPYINFO. */
392 x_destroy_all_bitmaps (Display_Info
*dpyinfo
)
395 Bitmap_Record
*bm
= dpyinfo
->bitmaps
;
397 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++, bm
++)
398 if (bm
->refcount
> 0)
399 free_bitmap_record (dpyinfo
, bm
);
401 dpyinfo
->bitmaps_last
= 0;
404 static bool x_create_x_image_and_pixmap (struct frame
*, int, int, int,
405 XImagePtr
*, Pixmap
*);
406 static void x_destroy_x_image (XImagePtr ximg
);
409 static XImagePtr_or_DC
image_get_x_image_or_dc (struct frame
*, struct image
*,
411 static void image_unget_x_image_or_dc (struct image
*, bool, XImagePtr_or_DC
,
414 static XImagePtr
image_get_x_image (struct frame
*, struct image
*, bool);
415 static void image_unget_x_image (struct image
*, bool, XImagePtr
);
416 #define image_get_x_image_or_dc(f, img, mask_p, dummy) \
417 image_get_x_image (f, img, mask_p)
418 #define image_unget_x_image_or_dc(img, mask_p, ximg, dummy) \
419 image_unget_x_image (img, mask_p, ximg)
422 #ifdef HAVE_X_WINDOWS
424 static void image_sync_to_pixmaps (struct frame
*, struct image
*);
426 /* Useful functions defined in the section
427 `Image type independent image structures' below. */
429 static unsigned long four_corners_best (XImagePtr ximg
,
432 unsigned long height
);
435 /* Create a mask of a bitmap. Note is this not a perfect mask.
436 It's nicer with some borders in this context */
439 x_create_bitmap_mask (struct frame
*f
, ptrdiff_t id
)
442 XImagePtr ximg
, mask_img
;
443 unsigned long width
, height
;
446 unsigned long x
, y
, xp
, xm
, yp
, ym
;
449 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
454 pixmap
= x_bitmap_pixmap (f
, id
);
455 width
= x_bitmap_width (f
, id
);
456 height
= x_bitmap_height (f
, id
);
459 ximg
= XGetImage (FRAME_X_DISPLAY (f
), pixmap
, 0, 0, width
, height
,
468 result
= x_create_x_image_and_pixmap (f
, width
, height
, 1, &mask_img
, &mask
);
473 XDestroyImage (ximg
);
477 bg
= four_corners_best (ximg
, NULL
, width
, height
);
479 for (y
= 0; y
< ximg
->height
; ++y
)
481 for (x
= 0; x
< ximg
->width
; ++x
)
483 xp
= x
!= ximg
->width
- 1 ? x
+ 1 : 0;
484 xm
= x
!= 0 ? x
- 1 : ximg
->width
- 1;
485 yp
= y
!= ximg
->height
- 1 ? y
+ 1 : 0;
486 ym
= y
!= 0 ? y
- 1 : ximg
->height
- 1;
487 if (XGetPixel (ximg
, x
, y
) == bg
488 && XGetPixel (ximg
, x
, yp
) == bg
489 && XGetPixel (ximg
, x
, ym
) == bg
490 && XGetPixel (ximg
, xp
, y
) == bg
491 && XGetPixel (ximg
, xp
, yp
) == bg
492 && XGetPixel (ximg
, xp
, ym
) == bg
493 && XGetPixel (ximg
, xm
, y
) == bg
494 && XGetPixel (ximg
, xm
, yp
) == bg
495 && XGetPixel (ximg
, xm
, ym
) == bg
)
496 XPutPixel (mask_img
, x
, y
, 0);
498 XPutPixel (mask_img
, x
, y
, 1);
502 eassert (input_blocked_p ());
503 gc
= XCreateGC (FRAME_X_DISPLAY (f
), mask
, 0, NULL
);
504 XPutImage (FRAME_X_DISPLAY (f
), mask
, gc
, mask_img
, 0, 0, 0, 0,
506 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
508 dpyinfo
->bitmaps
[id
- 1].have_mask
= true;
509 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
511 XDestroyImage (ximg
);
512 x_destroy_x_image (mask_img
);
515 #endif /* HAVE_X_WINDOWS */
517 /***********************************************************************
519 ***********************************************************************/
521 /* List of supported image types. Use define_image_type to add new
522 types. Use lookup_image_type to find a type for a given symbol. */
524 static struct image_type
*image_types
;
526 /* Forward function prototypes. */
528 static struct image_type
*lookup_image_type (Lisp_Object
);
529 static void x_laplace (struct frame
*, struct image
*);
530 static void x_emboss (struct frame
*, struct image
*);
531 static void x_build_heuristic_mask (struct frame
*, struct image
*,
534 #define CACHE_IMAGE_TYPE(type, status) \
535 do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
537 #define CACHE_IMAGE_TYPE(type, status)
540 #define ADD_IMAGE_TYPE(type) \
541 do { Vimage_types = Fcons (type, Vimage_types); } while (0)
543 /* Define a new image type from TYPE. This adds a copy of TYPE to
544 image_types and caches the loading status of TYPE. */
546 static struct image_type
*
547 define_image_type (struct image_type
*type
)
549 struct image_type
*p
= NULL
;
550 int new_type
= type
->type
;
551 bool type_valid
= true;
555 for (p
= image_types
; p
; p
= p
->next
)
556 if (p
->type
== new_type
)
561 #if defined HAVE_NTGUI && defined WINDOWSNT
562 /* If we failed to load the library before, don't try again. */
563 Lisp_Object tested
= Fassq (builtin_lisp_symbol (new_type
),
565 if (CONSP (tested
) && NILP (XCDR (tested
)))
570 type_valid
= type
->init ();
571 CACHE_IMAGE_TYPE (builtin_lisp_symbol (new_type
),
572 type_valid
? Qt
: Qnil
);
578 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
579 The initialized data segment is read-only. */
580 p
= xmalloc (sizeof *p
);
582 p
->next
= image_types
;
592 /* Value is true if OBJECT is a valid Lisp image specification. A
593 valid image specification is a list whose car is the symbol
594 `image', and whose rest is a property list. The property list must
595 contain a value for key `:type'. That value must be the name of a
596 supported image type. The rest of the property list depends on the
600 valid_image_p (Lisp_Object object
)
608 for (tem
= XCDR (object
); CONSP (tem
); tem
= XCDR (tem
))
609 if (EQ (XCAR (tem
), QCtype
))
612 if (CONSP (tem
) && SYMBOLP (XCAR (tem
)))
614 struct image_type
*type
;
615 type
= lookup_image_type (XCAR (tem
));
617 valid_p
= type
->valid_p (object
);
628 /* Log error message with format string FORMAT and trailing arguments.
629 Signaling an error, e.g. when an image cannot be loaded, is not a
630 good idea because this would interrupt redisplay, and the error
631 message display would lead to another redisplay. This function
632 therefore simply displays a message. */
635 image_error (const char *format
, ...)
638 va_start (ap
, format
);
639 vadd_to_log (format
, ap
);
644 image_size_error (void)
646 image_error ("Invalid image size (see `max-image-size')");
650 /***********************************************************************
652 ***********************************************************************/
654 enum image_value_type
656 IMAGE_DONT_CHECK_VALUE_TYPE
,
658 IMAGE_STRING_OR_NIL_VALUE
,
660 IMAGE_POSITIVE_INTEGER_VALUE
,
661 IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
,
662 IMAGE_NON_NEGATIVE_INTEGER_VALUE
,
665 IMAGE_FUNCTION_VALUE
,
670 /* Structure used when parsing image specifications. */
674 /* Name of keyword. */
677 /* The type of value allowed. */
678 enum image_value_type type
;
680 /* True means key must be present. */
683 /* Used to recognize duplicate keywords in a property list. */
686 /* The value that was found. */
691 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
692 has the format (image KEYWORD VALUE ...). One of the keyword/
693 value pairs must be `:type TYPE'. KEYWORDS is a vector of
694 image_keywords structures of size NKEYWORDS describing other
695 allowed keyword/value pairs. Value is true if SPEC is valid. */
698 parse_image_spec (Lisp_Object spec
, struct image_keyword
*keywords
,
699 int nkeywords
, Lisp_Object type
)
708 while (CONSP (plist
))
710 Lisp_Object key
, value
;
712 /* First element of a pair must be a symbol. */
714 plist
= XCDR (plist
);
718 /* There must follow a value. */
721 value
= XCAR (plist
);
722 plist
= XCDR (plist
);
724 /* Find key in KEYWORDS. Error if not found. */
725 for (i
= 0; i
< nkeywords
; ++i
)
726 if (strcmp (keywords
[i
].name
, SSDATA (SYMBOL_NAME (key
))) == 0)
732 /* Record that we recognized the keyword. If a keywords
733 was found more than once, it's an error. */
734 keywords
[i
].value
= value
;
735 if (keywords
[i
].count
> 1)
739 /* Check type of value against allowed type. */
740 switch (keywords
[i
].type
)
742 case IMAGE_STRING_VALUE
:
743 if (!STRINGP (value
))
747 case IMAGE_STRING_OR_NIL_VALUE
:
748 if (!STRINGP (value
) && !NILP (value
))
752 case IMAGE_SYMBOL_VALUE
:
753 if (!SYMBOLP (value
))
757 case IMAGE_POSITIVE_INTEGER_VALUE
:
758 if (! RANGED_INTEGERP (1, value
, INT_MAX
))
762 case IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
:
763 if (RANGED_INTEGERP (0, value
, INT_MAX
))
766 && RANGED_INTEGERP (0, XCAR (value
), INT_MAX
)
767 && RANGED_INTEGERP (0, XCDR (value
), INT_MAX
))
771 case IMAGE_ASCENT_VALUE
:
772 if (SYMBOLP (value
) && EQ (value
, Qcenter
))
774 else if (RANGED_INTEGERP (0, value
, 100))
778 case IMAGE_NON_NEGATIVE_INTEGER_VALUE
:
779 /* Unlike the other integer-related cases, this one does not
780 verify that VALUE fits in 'int'. This is because callers
782 if (!INTEGERP (value
) || XINT (value
) < 0)
786 case IMAGE_DONT_CHECK_VALUE_TYPE
:
789 case IMAGE_FUNCTION_VALUE
:
790 value
= indirect_function (value
);
791 if (!NILP (Ffunctionp (value
)))
795 case IMAGE_NUMBER_VALUE
:
796 if (! NUMBERP (value
))
800 case IMAGE_INTEGER_VALUE
:
801 if (! TYPE_RANGED_INTEGERP (int, value
))
805 case IMAGE_BOOL_VALUE
:
806 if (!NILP (value
) && !EQ (value
, Qt
))
815 if (EQ (key
, QCtype
) && !EQ (type
, value
))
819 /* Check that all mandatory fields are present. */
820 for (i
= 0; i
< nkeywords
; ++i
)
821 if (keywords
[i
].mandatory_p
&& keywords
[i
].count
== 0)
828 /* Return the value of KEY in image specification SPEC. Value is nil
829 if KEY is not present in SPEC. Set *FOUND depending on whether KEY
830 was found in SPEC. */
833 image_spec_value (Lisp_Object spec
, Lisp_Object key
, bool *found
)
837 eassert (valid_image_p (spec
));
839 for (tail
= XCDR (spec
);
840 CONSP (tail
) && CONSP (XCDR (tail
));
841 tail
= XCDR (XCDR (tail
)))
843 if (EQ (XCAR (tail
), key
))
847 return XCAR (XCDR (tail
));
857 DEFUN ("image-size", Fimage_size
, Simage_size
, 1, 3, 0,
858 doc
: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
859 PIXELS non-nil means return the size in pixels, otherwise return the
860 size in canonical character units.
861 FRAME is the frame on which the image will be displayed. FRAME nil
862 or omitted means use the selected frame. */)
863 (Lisp_Object spec
, Lisp_Object pixels
, Lisp_Object frame
)
868 if (valid_image_p (spec
))
870 struct frame
*f
= decode_window_system_frame (frame
);
871 ptrdiff_t id
= lookup_image (f
, spec
);
872 struct image
*img
= IMAGE_FROM_ID (f
, id
);
873 int width
= img
->width
+ 2 * img
->hmargin
;
874 int height
= img
->height
+ 2 * img
->vmargin
;
877 size
= Fcons (make_float ((double) width
/ FRAME_COLUMN_WIDTH (f
)),
878 make_float ((double) height
/ FRAME_LINE_HEIGHT (f
)));
880 size
= Fcons (make_number (width
), make_number (height
));
883 error ("Invalid image specification");
889 DEFUN ("image-mask-p", Fimage_mask_p
, Simage_mask_p
, 1, 2, 0,
890 doc
: /* Return t if image SPEC has a mask bitmap.
891 FRAME is the frame on which the image will be displayed. FRAME nil
892 or omitted means use the selected frame. */)
893 (Lisp_Object spec
, Lisp_Object frame
)
898 if (valid_image_p (spec
))
900 struct frame
*f
= decode_window_system_frame (frame
);
901 ptrdiff_t id
= lookup_image (f
, spec
);
902 struct image
*img
= IMAGE_FROM_ID (f
, id
);
907 error ("Invalid image specification");
912 DEFUN ("image-metadata", Fimage_metadata
, Simage_metadata
, 1, 2, 0,
913 doc
: /* Return metadata for image SPEC.
914 FRAME is the frame on which the image will be displayed. FRAME nil
915 or omitted means use the selected frame. */)
916 (Lisp_Object spec
, Lisp_Object frame
)
921 if (valid_image_p (spec
))
923 struct frame
*f
= decode_window_system_frame (frame
);
924 ptrdiff_t id
= lookup_image (f
, spec
);
925 struct image
*img
= IMAGE_FROM_ID (f
, id
);
926 ext
= img
->lisp_data
;
933 /***********************************************************************
934 Image type independent image structures
935 ***********************************************************************/
937 #define MAX_IMAGE_SIZE 10.0
938 /* Allocate and return a new image structure for image specification
939 SPEC. SPEC has a hash value of HASH. */
941 static struct image
*
942 make_image (Lisp_Object spec
, EMACS_UINT hash
)
944 struct image
*img
= xzalloc (sizeof *img
);
945 Lisp_Object file
= image_spec_value (spec
, QCfile
, NULL
);
947 eassert (valid_image_p (spec
));
948 img
->dependencies
= NILP (file
) ? Qnil
: list1 (file
);
949 img
->type
= lookup_image_type (image_spec_value (spec
, QCtype
, NULL
));
950 eassert (img
->type
!= NULL
);
952 img
->lisp_data
= Qnil
;
953 img
->ascent
= DEFAULT_IMAGE_ASCENT
;
955 img
->corners
[BOT_CORNER
] = -1; /* Full image */
960 /* Free image IMG which was used on frame F, including its resources. */
963 free_image (struct frame
*f
, struct image
*img
)
967 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
969 /* Remove IMG from the hash table of its cache. */
971 img
->prev
->next
= img
->next
;
973 c
->buckets
[img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
] = img
->next
;
976 img
->next
->prev
= img
->prev
;
978 c
->images
[img
->id
] = NULL
;
980 /* Windows NT redefines 'free', but in this file, we need to
981 avoid the redefinition. */
985 /* Free resources, then free IMG. */
986 img
->type
->free (f
, img
);
991 /* Return true if the given widths and heights are valid for display. */
994 check_image_size (struct frame
*f
, int width
, int height
)
998 if (width
<= 0 || height
<= 0)
1001 if (INTEGERP (Vmax_image_size
))
1002 return (width
<= XINT (Vmax_image_size
)
1003 && height
<= XINT (Vmax_image_size
));
1004 else if (FLOATP (Vmax_image_size
))
1008 w
= FRAME_PIXEL_WIDTH (f
);
1009 h
= FRAME_PIXEL_HEIGHT (f
);
1012 w
= h
= 1024; /* Arbitrary size for unknown frame. */
1013 return (width
<= XFLOAT_DATA (Vmax_image_size
) * w
1014 && height
<= XFLOAT_DATA (Vmax_image_size
) * h
);
1020 /* Prepare image IMG for display on frame F. Must be called before
1021 drawing an image. */
1024 prepare_image_for_display (struct frame
*f
, struct image
*img
)
1026 /* We're about to display IMG, so set its timestamp to `now'. */
1027 img
->timestamp
= current_timespec ();
1030 /* If IMG doesn't have a pixmap yet, load it now, using the image
1031 type dependent loader function. */
1032 if (img
->pixmap
== NO_PIXMAP
&& !img
->load_failed_p
)
1033 img
->load_failed_p
= ! img
->type
->load (f
, img
);
1035 #ifdef HAVE_X_WINDOWS
1036 if (!img
->load_failed_p
)
1039 image_sync_to_pixmaps (f
, img
);
1047 /* Value is the number of pixels for the ascent of image IMG when
1048 drawn in face FACE. */
1051 image_ascent (struct image
*img
, struct face
*face
, struct glyph_slice
*slice
)
1056 if (slice
->height
== img
->height
)
1057 height
= img
->height
+ img
->vmargin
;
1058 else if (slice
->y
== 0)
1059 height
= slice
->height
+ img
->vmargin
;
1061 height
= slice
->height
;
1063 if (img
->ascent
== CENTERED_IMAGE_ASCENT
)
1068 /* W32 specific version. Why?. ++kfs */
1069 ascent
= height
/ 2 - (FONT_DESCENT (face
->font
)
1070 - FONT_BASE (face
->font
)) / 2;
1072 /* This expression is arranged so that if the image can't be
1073 exactly centered, it will be moved slightly up. This is
1074 because a typical font is `top-heavy' (due to the presence
1075 uppercase letters), so the image placement should err towards
1076 being top-heavy too. It also just generally looks better. */
1077 ascent
= (height
+ FONT_BASE (face
->font
)
1078 - FONT_DESCENT (face
->font
) + 1) / 2;
1079 #endif /* HAVE_NTGUI */
1082 ascent
= height
/ 2;
1085 ascent
= height
* (img
->ascent
/ 100.0);
1092 xcolor_to_argb32 (XColor xc
)
1094 return (0xff << 24) | ((xc
.red
/ 256) << 16)
1095 | ((xc
.green
/ 256) << 8) | (xc
.blue
/ 256);
1099 get_spec_bg_or_alpha_as_argb (struct image
*img
,
1102 uint32_t bgcolor
= 0;
1104 Lisp_Object bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
1106 if (STRINGP (bg
) && x_parse_color (f
, SSDATA (bg
), &xbgcolor
))
1107 bgcolor
= xcolor_to_argb32 (xbgcolor
);
1113 create_cairo_image_surface (struct image
*img
,
1114 unsigned char *data
,
1118 cairo_surface_t
*surface
;
1119 cairo_format_t format
= CAIRO_FORMAT_ARGB32
;
1120 int stride
= cairo_format_stride_for_width (format
, width
);
1121 surface
= cairo_image_surface_create_for_data (data
,
1127 img
->height
= height
;
1128 img
->cr_data
= surface
;
1129 img
->cr_data2
= data
;
1136 /* Image background colors. */
1138 /* Find the "best" corner color of a bitmap.
1139 On W32, XIMG is assumed to a device context with the bitmap selected. */
1141 static RGB_PIXEL_COLOR
1142 four_corners_best (XImagePtr_or_DC ximg
, int *corners
,
1143 unsigned long width
, unsigned long height
)
1145 RGB_PIXEL_COLOR corner_pixels
[4], best
IF_LINT (= 0);
1148 if (corners
&& corners
[BOT_CORNER
] >= 0)
1150 /* Get the colors at the corner_pixels of ximg. */
1151 corner_pixels
[0] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[TOP_CORNER
]);
1152 corner_pixels
[1] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[TOP_CORNER
]);
1153 corner_pixels
[2] = GET_PIXEL (ximg
, corners
[RIGHT_CORNER
] - 1, corners
[BOT_CORNER
] - 1);
1154 corner_pixels
[3] = GET_PIXEL (ximg
, corners
[LEFT_CORNER
], corners
[BOT_CORNER
] - 1);
1158 /* Get the colors at the corner_pixels of ximg. */
1159 corner_pixels
[0] = GET_PIXEL (ximg
, 0, 0);
1160 corner_pixels
[1] = GET_PIXEL (ximg
, width
- 1, 0);
1161 corner_pixels
[2] = GET_PIXEL (ximg
, width
- 1, height
- 1);
1162 corner_pixels
[3] = GET_PIXEL (ximg
, 0, height
- 1);
1164 /* Choose the most frequently found color as background. */
1165 for (i
= best_count
= 0; i
< 4; ++i
)
1169 for (j
= n
= 0; j
< 4; ++j
)
1170 if (corner_pixels
[i
] == corner_pixels
[j
])
1174 best
= corner_pixels
[i
], best_count
= n
;
1180 /* Portability macros */
1184 #define Free_Pixmap(display, pixmap) \
1185 DeleteObject (pixmap)
1187 #elif defined (HAVE_NS)
1189 #define Free_Pixmap(display, pixmap) \
1190 ns_release_object (pixmap)
1194 #define Free_Pixmap(display, pixmap) \
1195 XFreePixmap (display, pixmap)
1197 #endif /* !HAVE_NTGUI && !HAVE_NS */
1200 /* Return the `background' field of IMG. If IMG doesn't have one yet,
1201 it is guessed heuristically. If non-zero, XIMG is an existing
1202 XImage object (or device context with the image selected on W32) to
1203 use for the heuristic. */
1206 image_background (struct image
*img
, struct frame
*f
, XImagePtr_or_DC ximg
)
1208 if (! img
->background_valid
)
1209 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1211 bool free_ximg
= !ximg
;
1214 #endif /* HAVE_NTGUI */
1217 ximg
= image_get_x_image_or_dc (f
, img
, 0, &prev
);
1219 img
->background
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
1222 image_unget_x_image_or_dc (img
, 0, ximg
, prev
);
1224 img
->background_valid
= 1;
1227 return img
->background
;
1230 /* Return the `background_transparent' field of IMG. If IMG doesn't
1231 have one yet, it is guessed heuristically. If non-zero, MASK is an
1232 existing XImage object to use for the heuristic. */
1235 image_background_transparent (struct image
*img
, struct frame
*f
, XImagePtr_or_DC mask
)
1237 if (! img
->background_transparent_valid
)
1238 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1242 bool free_mask
= !mask
;
1245 #endif /* HAVE_NTGUI */
1248 mask
= image_get_x_image_or_dc (f
, img
, 1, &prev
);
1250 img
->background_transparent
1251 = (four_corners_best (mask
, img
->corners
, img
->width
, img
->height
) == PIX_MASK_RETAIN
);
1254 image_unget_x_image_or_dc (img
, 1, mask
, prev
);
1257 img
->background_transparent
= 0;
1259 img
->background_transparent_valid
= 1;
1262 return img
->background_transparent
;
1265 #if defined (HAVE_PNG) || defined (HAVE_NS) \
1266 || defined (HAVE_IMAGEMAGICK) || defined (HAVE_RSVG)
1268 /* Store F's background color into *BGCOLOR. */
1270 x_query_frame_background_color (struct frame
*f
, XColor
*bgcolor
)
1273 bgcolor
->pixel
= FRAME_BACKGROUND_PIXEL (f
);
1274 x_query_color (f
, bgcolor
);
1276 ns_query_color (FRAME_BACKGROUND_COLOR (f
), bgcolor
, 1);
1280 #endif /* HAVE_PNG || HAVE_NS || HAVE_IMAGEMAGICK || HAVE_RSVG */
1282 /***********************************************************************
1283 Helper functions for X image types
1284 ***********************************************************************/
1286 /* Clear X resources of image IMG on frame F according to FLAGS.
1287 FLAGS is bitwise-or of the following masks:
1288 CLEAR_IMAGE_PIXMAP free the pixmap if any.
1289 CLEAR_IMAGE_MASK means clear the mask pixmap if any.
1290 CLEAR_IMAGE_COLORS means free colors allocated for the image, if
1293 #define CLEAR_IMAGE_PIXMAP (1 << 0)
1294 #define CLEAR_IMAGE_MASK (1 << 1)
1295 #define CLEAR_IMAGE_COLORS (1 << 2)
1298 x_clear_image_1 (struct frame
*f
, struct image
*img
, int flags
)
1300 if (flags
& CLEAR_IMAGE_PIXMAP
)
1304 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->pixmap
);
1305 img
->pixmap
= NO_PIXMAP
;
1306 /* NOTE (HAVE_NS): background color is NOT an indexed color! */
1307 img
->background_valid
= 0;
1309 #ifdef HAVE_X_WINDOWS
1312 x_destroy_x_image (img
->ximg
);
1314 img
->background_valid
= 0;
1319 if (flags
& CLEAR_IMAGE_MASK
)
1323 Free_Pixmap (FRAME_X_DISPLAY (f
), img
->mask
);
1324 img
->mask
= NO_PIXMAP
;
1325 img
->background_transparent_valid
= 0;
1327 #ifdef HAVE_X_WINDOWS
1330 x_destroy_x_image (img
->mask_img
);
1331 img
->mask_img
= NULL
;
1332 img
->background_transparent_valid
= 0;
1337 if ((flags
& CLEAR_IMAGE_COLORS
) && img
->ncolors
)
1339 /* W32_TODO: color table support. */
1340 #ifdef HAVE_X_WINDOWS
1341 x_free_colors (f
, img
->colors
, img
->ncolors
);
1342 #endif /* HAVE_X_WINDOWS */
1343 xfree (img
->colors
);
1350 /* Free X resources of image IMG which is used on frame F. */
1353 x_clear_image (struct frame
*f
, struct image
*img
)
1358 cairo_surface_destroy ((cairo_surface_t
*)img
->cr_data
);
1359 if (img
->cr_data2
) xfree (img
->cr_data2
);
1361 x_clear_image_1 (f
, img
,
1362 CLEAR_IMAGE_PIXMAP
| CLEAR_IMAGE_MASK
| CLEAR_IMAGE_COLORS
);
1367 /* Allocate color COLOR_NAME for image IMG on frame F. If color
1368 cannot be allocated, use DFLT. Add a newly allocated color to
1369 IMG->colors, so that it can be freed again. Value is the pixel
1372 static unsigned long
1373 x_alloc_image_color (struct frame
*f
, struct image
*img
, Lisp_Object color_name
,
1377 unsigned long result
;
1379 eassert (STRINGP (color_name
));
1381 if (x_defined_color (f
, SSDATA (color_name
), &color
, 1)
1382 && img
->ncolors
< min (min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *img
->colors
,
1385 /* This isn't called frequently so we get away with simply
1386 reallocating the color vector to the needed size, here. */
1387 ptrdiff_t ncolors
= img
->ncolors
+ 1;
1388 img
->colors
= xrealloc (img
->colors
, ncolors
* sizeof *img
->colors
);
1389 img
->colors
[ncolors
- 1] = color
.pixel
;
1390 img
->ncolors
= ncolors
;
1391 result
= color
.pixel
;
1401 /***********************************************************************
1403 ***********************************************************************/
1405 static void cache_image (struct frame
*f
, struct image
*img
);
1407 /* Return a new, initialized image cache that is allocated from the
1408 heap. Call free_image_cache to free an image cache. */
1410 struct image_cache
*
1411 make_image_cache (void)
1413 struct image_cache
*c
= xmalloc (sizeof *c
);
1416 c
->used
= c
->refcount
= 0;
1417 c
->images
= xmalloc (c
->size
* sizeof *c
->images
);
1418 c
->buckets
= xzalloc (IMAGE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
);
1423 /* Find an image matching SPEC in the cache, and return it. If no
1424 image is found, return NULL. */
1425 static struct image
*
1426 search_image_cache (struct frame
*f
, Lisp_Object spec
, EMACS_UINT hash
)
1429 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1430 int i
= hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1432 if (!c
) return NULL
;
1434 /* If the image spec does not specify a background color, the cached
1435 image must have the same background color as the current frame.
1436 The foreground color must also match, for the sake of monochrome
1439 In fact, we could ignore the foreground color matching condition
1440 for color images, or if the image spec specifies :foreground;
1441 similarly we could ignore the background color matching condition
1442 for formats that don't use transparency (such as jpeg), or if the
1443 image spec specifies :background. However, the extra memory
1444 usage is probably negligible in practice, so we don't bother. */
1446 for (img
= c
->buckets
[i
]; img
; img
= img
->next
)
1447 if (img
->hash
== hash
1448 && !NILP (Fequal (img
->spec
, spec
))
1449 && img
->frame_foreground
== FRAME_FOREGROUND_PIXEL (f
)
1450 && img
->frame_background
== FRAME_BACKGROUND_PIXEL (f
))
1456 /* Search frame F for an image with spec SPEC, and free it. */
1459 uncache_image (struct frame
*f
, Lisp_Object spec
)
1461 struct image
*img
= search_image_cache (f
, spec
, sxhash (spec
, 0));
1464 free_image (f
, img
);
1465 /* As display glyphs may still be referring to the image ID, we
1466 must garbage the frame (Bug#6426). */
1467 SET_FRAME_GARBAGED (f
);
1472 /* Free image cache of frame F. Be aware that X frames share images
1476 free_image_cache (struct frame
*f
)
1478 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1483 /* Cache should not be referenced by any frame when freed. */
1484 eassert (c
->refcount
== 0);
1486 for (i
= 0; i
< c
->used
; ++i
)
1487 free_image (f
, c
->images
[i
]);
1491 FRAME_IMAGE_CACHE (f
) = NULL
;
1496 /* Clear image cache of frame F. FILTER=t means free all images.
1497 FILTER=nil means clear only images that haven't been
1498 displayed for some time.
1499 Else, only free the images which have FILTER in their `dependencies'.
1500 Should be called from time to time to reduce the number of loaded images.
1501 If image-cache-eviction-delay is non-nil, this frees images in the cache
1502 which weren't displayed for at least that many seconds. */
1505 clear_image_cache (struct frame
*f
, Lisp_Object filter
)
1507 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1511 ptrdiff_t i
, nfreed
= 0;
1513 /* Block input so that we won't be interrupted by a SIGIO
1514 while being in an inconsistent state. */
1519 /* Filter image cache. */
1520 for (i
= 0; i
< c
->used
; ++i
)
1522 struct image
*img
= c
->images
[i
];
1523 if (img
&& (EQ (Qt
, filter
)
1524 || !NILP (Fmember (filter
, img
->dependencies
))))
1526 free_image (f
, img
);
1531 else if (INTEGERP (Vimage_cache_eviction_delay
))
1533 /* Free cache based on timestamp. */
1534 struct timespec old
, t
;
1536 ptrdiff_t nimages
= 0;
1538 for (i
= 0; i
< c
->used
; ++i
)
1542 /* If the number of cached images has grown unusually large,
1543 decrease the cache eviction delay (Bug#6230). */
1544 delay
= XINT (Vimage_cache_eviction_delay
);
1546 delay
= 1600 * delay
/ nimages
/ nimages
;
1547 delay
= max (delay
, 1);
1549 t
= current_timespec ();
1550 old
= timespec_sub (t
, dtotimespec (delay
));
1552 for (i
= 0; i
< c
->used
; ++i
)
1554 struct image
*img
= c
->images
[i
];
1555 if (img
&& timespec_cmp (img
->timestamp
, old
) < 0)
1557 free_image (f
, img
);
1563 /* We may be clearing the image cache because, for example,
1564 Emacs was iconified for a longer period of time. In that
1565 case, current matrices may still contain references to
1566 images freed above. So, clear these matrices. */
1569 Lisp_Object tail
, frame
;
1571 FOR_EACH_FRAME (tail
, frame
)
1573 struct frame
*fr
= XFRAME (frame
);
1574 if (FRAME_IMAGE_CACHE (fr
) == c
)
1575 clear_current_matrices (fr
);
1578 windows_or_buffers_changed
= 19;
1586 clear_image_caches (Lisp_Object filter
)
1588 /* FIXME: We want to do
1589 * struct terminal *t;
1590 * for (t = terminal_list; t; t = t->next_terminal)
1591 * clear_image_cache (t, filter); */
1592 Lisp_Object tail
, frame
;
1593 FOR_EACH_FRAME (tail
, frame
)
1594 if (FRAME_WINDOW_P (XFRAME (frame
)))
1595 clear_image_cache (XFRAME (frame
), filter
);
1598 DEFUN ("clear-image-cache", Fclear_image_cache
, Sclear_image_cache
,
1600 doc
: /* Clear the image cache.
1601 FILTER nil or a frame means clear all images in the selected frame.
1602 FILTER t means clear the image caches of all frames.
1603 Anything else, means only clear those images which refer to FILTER,
1604 which is then usually a filename. */)
1605 (Lisp_Object filter
)
1607 if (!(EQ (filter
, Qnil
) || FRAMEP (filter
)))
1608 clear_image_caches (filter
);
1610 clear_image_cache (decode_window_system_frame (filter
), Qt
);
1616 DEFUN ("image-flush", Fimage_flush
, Simage_flush
,
1618 doc
: /* Flush the image with specification SPEC on frame FRAME.
1619 This removes the image from the Emacs image cache. If SPEC specifies
1620 an image file, the next redisplay of this image will read from the
1621 current contents of that file.
1623 FRAME nil or omitted means use the selected frame.
1624 FRAME t means refresh the image on all frames. */)
1625 (Lisp_Object spec
, Lisp_Object frame
)
1627 if (!valid_image_p (spec
))
1628 error ("Invalid image specification");
1633 FOR_EACH_FRAME (tail
, frame
)
1635 struct frame
*f
= XFRAME (frame
);
1636 if (FRAME_WINDOW_P (f
))
1637 uncache_image (f
, spec
);
1641 uncache_image (decode_window_system_frame (frame
), spec
);
1647 /* Compute masks and transform image IMG on frame F, as specified
1648 by the image's specification, */
1651 postprocess_image (struct frame
*f
, struct image
*img
)
1653 /* Manipulation of the image's mask. */
1656 Lisp_Object conversion
, spec
;
1661 /* `:heuristic-mask t'
1663 means build a mask heuristically.
1664 `:heuristic-mask (R G B)'
1665 `:mask (heuristic (R G B))'
1666 means build a mask from color (R G B) in the
1669 means remove a mask, if any. */
1671 mask
= image_spec_value (spec
, QCheuristic_mask
, NULL
);
1673 x_build_heuristic_mask (f
, img
, mask
);
1678 mask
= image_spec_value (spec
, QCmask
, &found_p
);
1680 if (EQ (mask
, Qheuristic
))
1681 x_build_heuristic_mask (f
, img
, Qt
);
1682 else if (CONSP (mask
)
1683 && EQ (XCAR (mask
), Qheuristic
))
1685 if (CONSP (XCDR (mask
)))
1686 x_build_heuristic_mask (f
, img
, XCAR (XCDR (mask
)));
1688 x_build_heuristic_mask (f
, img
, XCDR (mask
));
1690 else if (NILP (mask
) && found_p
&& img
->mask
)
1691 x_clear_image_1 (f
, img
, CLEAR_IMAGE_MASK
);
1695 /* Should we apply an image transformation algorithm? */
1696 conversion
= image_spec_value (spec
, QCconversion
, NULL
);
1697 if (EQ (conversion
, Qdisabled
))
1698 x_disable_image (f
, img
);
1699 else if (EQ (conversion
, Qlaplace
))
1701 else if (EQ (conversion
, Qemboss
))
1703 else if (CONSP (conversion
)
1704 && EQ (XCAR (conversion
), Qedge_detection
))
1707 tem
= XCDR (conversion
);
1709 x_edge_detection (f
, img
,
1710 Fplist_get (tem
, QCmatrix
),
1711 Fplist_get (tem
, QCcolor_adjustment
));
1717 /* Return the id of image with Lisp specification SPEC on frame F.
1718 SPEC must be a valid Lisp image specification (see valid_image_p). */
1721 lookup_image (struct frame
*f
, Lisp_Object spec
)
1726 /* F must be a window-system frame, and SPEC must be a valid image
1728 eassert (FRAME_WINDOW_P (f
));
1729 eassert (valid_image_p (spec
));
1731 /* Look up SPEC in the hash table of the image cache. */
1732 hash
= sxhash (spec
, 0);
1733 img
= search_image_cache (f
, spec
, hash
);
1734 if (img
&& img
->load_failed_p
)
1736 free_image (f
, img
);
1740 /* If not found, create a new image and cache it. */
1744 img
= make_image (spec
, hash
);
1745 cache_image (f
, img
);
1746 img
->load_failed_p
= ! img
->type
->load (f
, img
);
1747 img
->frame_foreground
= FRAME_FOREGROUND_PIXEL (f
);
1748 img
->frame_background
= FRAME_BACKGROUND_PIXEL (f
);
1750 /* If we can't load the image, and we don't have a width and
1751 height, use some arbitrary width and height so that we can
1752 draw a rectangle for it. */
1753 if (img
->load_failed_p
)
1757 value
= image_spec_value (spec
, QCwidth
, NULL
);
1758 img
->width
= (INTEGERP (value
)
1759 ? XFASTINT (value
) : DEFAULT_IMAGE_WIDTH
);
1760 value
= image_spec_value (spec
, QCheight
, NULL
);
1761 img
->height
= (INTEGERP (value
)
1762 ? XFASTINT (value
) : DEFAULT_IMAGE_HEIGHT
);
1766 /* Handle image type independent image attributes
1767 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
1768 `:background COLOR'. */
1769 Lisp_Object ascent
, margin
, relief
, bg
;
1772 ascent
= image_spec_value (spec
, QCascent
, NULL
);
1773 if (INTEGERP (ascent
))
1774 img
->ascent
= XFASTINT (ascent
);
1775 else if (EQ (ascent
, Qcenter
))
1776 img
->ascent
= CENTERED_IMAGE_ASCENT
;
1778 margin
= image_spec_value (spec
, QCmargin
, NULL
);
1779 if (INTEGERP (margin
))
1780 img
->vmargin
= img
->hmargin
= XFASTINT (margin
);
1781 else if (CONSP (margin
))
1783 img
->hmargin
= XFASTINT (XCAR (margin
));
1784 img
->vmargin
= XFASTINT (XCDR (margin
));
1787 relief
= image_spec_value (spec
, QCrelief
, NULL
);
1788 relief_bound
= INT_MAX
- max (img
->hmargin
, img
->vmargin
);
1789 if (RANGED_INTEGERP (- relief_bound
, relief
, relief_bound
))
1791 img
->relief
= XINT (relief
);
1792 img
->hmargin
+= eabs (img
->relief
);
1793 img
->vmargin
+= eabs (img
->relief
);
1796 if (! img
->background_valid
)
1798 bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
1802 = x_alloc_image_color (f
, img
, bg
,
1803 FRAME_BACKGROUND_PIXEL (f
));
1804 img
->background_valid
= 1;
1808 /* Do image transformations and compute masks, unless we
1809 don't have the image yet. */
1810 if (!EQ (builtin_lisp_symbol (img
->type
->type
), Qpostscript
))
1811 postprocess_image (f
, img
);
1817 /* We're using IMG, so set its timestamp to `now'. */
1818 img
->timestamp
= current_timespec ();
1820 /* Value is the image id. */
1825 /* Cache image IMG in the image cache of frame F. */
1828 cache_image (struct frame
*f
, struct image
*img
)
1830 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
1834 c
= FRAME_IMAGE_CACHE (f
) = make_image_cache ();
1836 /* Find a free slot in c->images. */
1837 for (i
= 0; i
< c
->used
; ++i
)
1838 if (c
->images
[i
] == NULL
)
1841 /* If no free slot found, maybe enlarge c->images. */
1842 if (i
== c
->used
&& c
->used
== c
->size
)
1843 c
->images
= xpalloc (c
->images
, &c
->size
, 1, -1, sizeof *c
->images
);
1845 /* Add IMG to c->images, and assign IMG an id. */
1851 /* Add IMG to the cache's hash table. */
1852 i
= img
->hash
% IMAGE_CACHE_BUCKETS_SIZE
;
1853 img
->next
= c
->buckets
[i
];
1855 img
->next
->prev
= img
;
1857 c
->buckets
[i
] = img
;
1861 /* Call FN on every image in the image cache of frame F. Used to mark
1862 Lisp Objects in the image cache. */
1864 /* Mark Lisp objects in image IMG. */
1867 mark_image (struct image
*img
)
1869 mark_object (img
->spec
);
1870 mark_object (img
->dependencies
);
1872 if (!NILP (img
->lisp_data
))
1873 mark_object (img
->lisp_data
);
1878 mark_image_cache (struct image_cache
*c
)
1883 for (i
= 0; i
< c
->used
; ++i
)
1885 mark_image (c
->images
[i
]);
1891 /***********************************************************************
1892 X / NS / W32 support code
1893 ***********************************************************************/
1895 /* Return true if XIMG's size WIDTH x HEIGHT doesn't break the
1897 WIDTH and HEIGHT must both be positive.
1898 If XIMG is null, assume it is a bitmap. */
1900 x_check_image_size (XImagePtr ximg
, int width
, int height
)
1902 #ifdef HAVE_X_WINDOWS
1903 /* Respect Xlib's limits: it cannot deal with images that have more
1904 than INT_MAX (and/or UINT_MAX) bytes. And respect Emacs's limits
1905 of PTRDIFF_MAX (and/or SIZE_MAX) bytes for any object. */
1908 XLIB_BYTES_MAX
= min (INT_MAX
, UINT_MAX
),
1909 X_IMAGE_BYTES_MAX
= min (XLIB_BYTES_MAX
, min (PTRDIFF_MAX
, SIZE_MAX
))
1912 int bitmap_pad
, depth
, bytes_per_line
;
1915 bitmap_pad
= ximg
->bitmap_pad
;
1916 depth
= ximg
->depth
;
1917 bytes_per_line
= ximg
->bytes_per_line
;
1923 bytes_per_line
= (width
>> 3) + ((width
& 7) != 0);
1925 return (width
<= (INT_MAX
- (bitmap_pad
- 1)) / depth
1926 && height
<= X_IMAGE_BYTES_MAX
/ bytes_per_line
);
1928 /* FIXME: Implement this check for the HAVE_NS and HAVE_NTGUI cases.
1929 For now, assume that every image size is allowed on these systems. */
1934 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
1935 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
1936 Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
1937 via xmalloc. Print error messages via image_error if an error
1938 occurs. Value is true if successful.
1940 On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
1941 should indicate the bit depth of the image. */
1944 x_create_x_image_and_pixmap (struct frame
*f
, int width
, int height
, int depth
,
1945 XImagePtr
*ximg
, Pixmap
*pixmap
)
1947 #ifdef HAVE_X_WINDOWS
1948 Display
*display
= FRAME_X_DISPLAY (f
);
1949 Window window
= FRAME_X_WINDOW (f
);
1950 Screen
*screen
= FRAME_X_SCREEN (f
);
1952 eassert (input_blocked_p ());
1955 depth
= DefaultDepthOfScreen (screen
);
1956 *ximg
= XCreateImage (display
, DefaultVisualOfScreen (screen
),
1957 depth
, ZPixmap
, 0, NULL
, width
, height
,
1958 depth
> 16 ? 32 : depth
> 8 ? 16 : 8, 0);
1961 image_error ("Unable to allocate X image");
1965 if (! x_check_image_size (*ximg
, width
, height
))
1967 x_destroy_x_image (*ximg
);
1969 image_error ("Image too large (%dx%d)",
1970 make_number (width
), make_number (height
));
1974 /* Allocate image raster. */
1975 (*ximg
)->data
= xmalloc ((*ximg
)->bytes_per_line
* height
);
1977 /* Allocate a pixmap of the same size. */
1978 *pixmap
= XCreatePixmap (display
, window
, width
, height
, depth
);
1979 if (*pixmap
== NO_PIXMAP
)
1981 x_destroy_x_image (*ximg
);
1983 image_error ("Unable to create X pixmap");
1988 #endif /* HAVE_X_WINDOWS */
1992 BITMAPINFOHEADER
*header
;
1994 int scanline_width_bits
;
1996 int palette_colors
= 0;
2001 if (depth
!= 1 && depth
!= 4 && depth
!= 8
2002 && depth
!= 16 && depth
!= 24 && depth
!= 32)
2004 image_error ("Invalid image bit depth specified");
2008 scanline_width_bits
= width
* depth
;
2009 remainder
= scanline_width_bits
% 32;
2012 scanline_width_bits
+= 32 - remainder
;
2014 /* Bitmaps with a depth less than 16 need a palette. */
2015 /* BITMAPINFO structure already contains the first RGBQUAD. */
2017 palette_colors
= 1 << (depth
- 1);
2019 *ximg
= xmalloc (sizeof (XImage
) + palette_colors
* sizeof (RGBQUAD
));
2021 header
= &(*ximg
)->info
.bmiHeader
;
2022 memset (&(*ximg
)->info
, 0, sizeof (BITMAPINFO
));
2023 header
->biSize
= sizeof (*header
);
2024 header
->biWidth
= width
;
2025 header
->biHeight
= -height
; /* negative indicates a top-down bitmap. */
2026 header
->biPlanes
= 1;
2027 header
->biBitCount
= depth
;
2028 header
->biCompression
= BI_RGB
;
2029 header
->biClrUsed
= palette_colors
;
2031 /* TODO: fill in palette. */
2034 (*ximg
)->info
.bmiColors
[0].rgbBlue
= 0;
2035 (*ximg
)->info
.bmiColors
[0].rgbGreen
= 0;
2036 (*ximg
)->info
.bmiColors
[0].rgbRed
= 0;
2037 (*ximg
)->info
.bmiColors
[0].rgbReserved
= 0;
2038 (*ximg
)->info
.bmiColors
[1].rgbBlue
= 255;
2039 (*ximg
)->info
.bmiColors
[1].rgbGreen
= 255;
2040 (*ximg
)->info
.bmiColors
[1].rgbRed
= 255;
2041 (*ximg
)->info
.bmiColors
[1].rgbReserved
= 0;
2044 hdc
= get_frame_dc (f
);
2046 /* Create a DIBSection and raster array for the bitmap,
2047 and store its handle in *pixmap. */
2048 *pixmap
= CreateDIBSection (hdc
, &((*ximg
)->info
),
2049 (depth
< 16) ? DIB_PAL_COLORS
: DIB_RGB_COLORS
,
2050 /* casting avoids a GCC warning */
2051 (void **)&((*ximg
)->data
), NULL
, 0);
2053 /* Realize display palette and garbage all frames. */
2054 release_frame_dc (f
, hdc
);
2056 if (*pixmap
== NULL
)
2058 DWORD err
= GetLastError ();
2059 Lisp_Object errcode
;
2060 /* All system errors are < 10000, so the following is safe. */
2061 XSETINT (errcode
, err
);
2062 image_error ("Unable to create bitmap, error code %d", errcode
);
2063 x_destroy_x_image (*ximg
);
2070 #endif /* HAVE_NTGUI */
2073 *pixmap
= ns_image_for_XPM (width
, height
, depth
);
2077 image_error ("Unable to allocate NSImage for XPM pixmap");
2086 /* Destroy XImage XIMG. Free XIMG->data. */
2089 x_destroy_x_image (XImagePtr ximg
)
2091 eassert (input_blocked_p ());
2094 #ifdef HAVE_X_WINDOWS
2097 XDestroyImage (ximg
);
2098 #endif /* HAVE_X_WINDOWS */
2100 /* Data will be freed by DestroyObject. */
2103 #endif /* HAVE_NTGUI */
2105 ns_release_object (ximg
);
2106 #endif /* HAVE_NS */
2111 /* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
2112 are width and height of both the image and pixmap. */
2115 x_put_x_image (struct frame
*f
, XImagePtr ximg
, Pixmap pixmap
, int width
, int height
)
2117 #ifdef HAVE_X_WINDOWS
2120 eassert (input_blocked_p ());
2121 gc
= XCreateGC (FRAME_X_DISPLAY (f
), pixmap
, 0, NULL
);
2122 XPutImage (FRAME_X_DISPLAY (f
), pixmap
, gc
, ximg
, 0, 0, 0, 0, width
, height
);
2123 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
2124 #endif /* HAVE_X_WINDOWS */
2127 #if 0 /* I don't think this is necessary looking at where it is used. */
2128 HDC hdc
= get_frame_dc (f
);
2129 SetDIBits (hdc
, pixmap
, 0, height
, ximg
->data
, &(ximg
->info
), DIB_RGB_COLORS
);
2130 release_frame_dc (f
, hdc
);
2132 #endif /* HAVE_NTGUI */
2135 eassert (ximg
== pixmap
);
2136 ns_retain_object (ximg
);
2140 /* Thin wrapper for x_create_x_image_and_pixmap, so that it matches
2141 with image_put_x_image. */
2144 image_create_x_image_and_pixmap (struct frame
*f
, struct image
*img
,
2145 int width
, int height
, int depth
,
2146 XImagePtr
*ximg
, bool mask_p
)
2148 eassert ((!mask_p
? img
->pixmap
: img
->mask
) == NO_PIXMAP
);
2150 return x_create_x_image_and_pixmap (f
, width
, height
, depth
, ximg
,
2151 !mask_p
? &img
->pixmap
: &img
->mask
);
2154 /* Put X image XIMG into image IMG on frame F, as a mask if and only
2155 if MASK_P. On X, this simply records XIMG on a member of IMG, so
2156 it can be put into the pixmap afterwards via image_sync_to_pixmaps.
2157 On the other platforms, it puts XIMG into the pixmap, then frees
2158 the X image and its buffer. */
2161 image_put_x_image (struct frame
*f
, struct image
*img
, XImagePtr ximg
,
2164 #ifdef HAVE_X_WINDOWS
2167 eassert (img
->ximg
== NULL
);
2172 eassert (img
->mask_img
== NULL
);
2173 img
->mask_img
= ximg
;
2176 x_put_x_image (f
, ximg
, !mask_p
? img
->pixmap
: img
->mask
,
2177 img
->width
, img
->height
);
2178 x_destroy_x_image (ximg
);
2182 #ifdef HAVE_X_WINDOWS
2183 /* Put the X images recorded in IMG on frame F into pixmaps, then free
2184 the X images and their buffers. */
2187 image_sync_to_pixmaps (struct frame
*f
, struct image
*img
)
2191 x_put_x_image (f
, img
->ximg
, img
->pixmap
, img
->width
, img
->height
);
2192 x_destroy_x_image (img
->ximg
);
2197 x_put_x_image (f
, img
->mask_img
, img
->mask
, img
->width
, img
->height
);
2198 x_destroy_x_image (img
->mask_img
);
2199 img
->mask_img
= NULL
;
2205 /* Create a memory device context for IMG on frame F. It stores the
2206 currently selected GDI object into *PREV for future restoration by
2207 image_unget_x_image_or_dc. */
2209 static XImagePtr_or_DC
2210 image_get_x_image_or_dc (struct frame
*f
, struct image
*img
, bool mask_p
,
2213 HDC frame_dc
= get_frame_dc (f
);
2214 XImagePtr_or_DC ximg
= CreateCompatibleDC (frame_dc
);
2216 release_frame_dc (f
, frame_dc
);
2217 *prev
= SelectObject (ximg
, !mask_p
? img
->pixmap
: img
->mask
);
2223 image_unget_x_image_or_dc (struct image
*img
, bool mask_p
,
2224 XImagePtr_or_DC ximg
, HGDIOBJ prev
)
2226 SelectObject (ximg
, prev
);
2229 #else /* !HAVE_NTGUI */
2230 /* Get the X image for IMG on frame F. The resulting X image data
2231 should be treated as read-only at least on X. */
2234 image_get_x_image (struct frame
*f
, struct image
*img
, bool mask_p
)
2236 #ifdef HAVE_X_WINDOWS
2237 XImagePtr ximg_in_img
= !mask_p
? img
->ximg
: img
->mask_img
;
2242 return XGetImage (FRAME_X_DISPLAY (f
), !mask_p
? img
->pixmap
: img
->mask
,
2243 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
2244 #elif defined (HAVE_NS)
2245 XImagePtr pixmap
= !mask_p
? img
->pixmap
: img
->mask
;
2247 ns_retain_object (pixmap
);
2253 image_unget_x_image (struct image
*img
, bool mask_p
, XImagePtr ximg
)
2255 #ifdef HAVE_X_WINDOWS
2256 XImagePtr ximg_in_img
= !mask_p
? img
->ximg
: img
->mask_img
;
2259 eassert (ximg
== ximg_in_img
);
2261 XDestroyImage (ximg
);
2262 #elif defined (HAVE_NS)
2263 ns_release_object (ximg
);
2266 #endif /* !HAVE_NTGUI */
2269 /***********************************************************************
2271 ***********************************************************************/
2273 /* Find image file FILE. Look in data-directory/images, then
2274 x-bitmap-file-path. Value is the full name of the file
2275 found, or nil if not found. If PFD is nonnull store into *PFD a
2276 readable file descriptor for the file, opened in binary mode. If
2277 PFD is null, do not open the file. */
2280 x_find_image_fd (Lisp_Object file
, int *pfd
)
2282 Lisp_Object file_found
, search_path
;
2285 /* TODO I think this should use something like image-load-path
2286 instead. Unfortunately, that can contain non-string elements. */
2287 search_path
= Fcons (Fexpand_file_name (build_string ("images"),
2289 Vx_bitmap_file_path
);
2291 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
2292 fd
= openp (search_path
, file
, Qnil
, &file_found
,
2293 pfd
? Qt
: make_number (R_OK
), false);
2294 if (fd
>= 0 || fd
== -2)
2296 file_found
= ENCODE_FILE (file_found
);
2299 /* The file exists locally, but has a file handler. (This
2300 happens, e.g., under Auto Image File Mode.) 'openp'
2301 didn't open the file, so we should, because the caller
2303 fd
= emacs_open (SSDATA (file_found
), O_RDONLY
| O_BINARY
, 0);
2306 else /* fd < 0, but not -2 */
2313 /* Find image file FILE. Look in data-directory/images, then
2314 x-bitmap-file-path. Value is the encoded full name of the file
2315 found, or nil if not found. */
2318 x_find_image_file (Lisp_Object file
)
2320 return x_find_image_fd (file
, 0);
2323 /* Read FILE into memory. Value is a pointer to a buffer allocated
2324 with xmalloc holding FILE's contents. Value is null if an error
2325 occurred. FD is a file descriptor open for reading FILE. Set
2326 *SIZE to the size of the file. */
2328 static unsigned char *
2329 slurp_file (int fd
, ptrdiff_t *size
)
2331 FILE *fp
= fdopen (fd
, "rb");
2333 unsigned char *buf
= NULL
;
2338 ptrdiff_t count
= SPECPDL_INDEX ();
2339 record_unwind_protect_ptr (fclose_unwind
, fp
);
2341 if (fstat (fileno (fp
), &st
) == 0
2342 && 0 <= st
.st_size
&& st
.st_size
< min (PTRDIFF_MAX
, SIZE_MAX
))
2344 /* Report an error if we read past the purported EOF.
2345 This can happen if the file grows as we read it. */
2346 ptrdiff_t buflen
= st
.st_size
;
2347 buf
= xmalloc (buflen
+ 1);
2348 if (fread (buf
, 1, buflen
+ 1, fp
) == buflen
)
2357 unbind_to (count
, Qnil
);
2365 /***********************************************************************
2367 ***********************************************************************/
2369 static bool xbm_load (struct frame
*f
, struct image
*img
);
2370 static bool xbm_image_p (Lisp_Object object
);
2371 static bool xbm_file_p (Lisp_Object
);
2374 /* Indices of image specification fields in xbm_format, below. */
2376 enum xbm_keyword_index
2394 /* Vector of image_keyword structures describing the format
2395 of valid XBM image specifications. */
2397 static const struct image_keyword xbm_format
[XBM_LAST
] =
2399 {":type", IMAGE_SYMBOL_VALUE
, 1},
2400 {":file", IMAGE_STRING_VALUE
, 0},
2401 {":width", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2402 {":height", IMAGE_POSITIVE_INTEGER_VALUE
, 0},
2403 {":data", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2404 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
2405 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
2406 {":ascent", IMAGE_ASCENT_VALUE
, 0},
2407 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
2408 {":relief", IMAGE_INTEGER_VALUE
, 0},
2409 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2410 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
2411 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
2414 /* Structure describing the image type XBM. */
2416 static struct image_type xbm_type
=
2418 SYMBOL_INDEX (Qxbm
),
2426 /* Tokens returned from xbm_scan. */
2435 /* Return true if OBJECT is a valid XBM-type image specification.
2436 A valid specification is a list starting with the symbol `image'
2437 The rest of the list is a property list which must contain an
2440 If the specification specifies a file to load, it must contain
2441 an entry `:file FILENAME' where FILENAME is a string.
2443 If the specification is for a bitmap loaded from memory it must
2444 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
2445 WIDTH and HEIGHT are integers > 0. DATA may be:
2447 1. a string large enough to hold the bitmap data, i.e. it must
2448 have a size >= (WIDTH + 7) / 8 * HEIGHT
2450 2. a bool-vector of size >= WIDTH * HEIGHT
2452 3. a vector of strings or bool-vectors, one for each line of the
2455 4. a string containing an in-memory XBM file. WIDTH and HEIGHT
2456 may not be specified in this case because they are defined in the
2459 Both the file and data forms may contain the additional entries
2460 `:background COLOR' and `:foreground COLOR'. If not present,
2461 foreground and background of the frame on which the image is
2462 displayed is used. */
2465 xbm_image_p (Lisp_Object object
)
2467 struct image_keyword kw
[XBM_LAST
];
2469 memcpy (kw
, xbm_format
, sizeof kw
);
2470 if (!parse_image_spec (object
, kw
, XBM_LAST
, Qxbm
))
2473 eassert (EQ (kw
[XBM_TYPE
].value
, Qxbm
));
2475 if (kw
[XBM_FILE
].count
)
2477 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_DATA
].count
)
2480 else if (kw
[XBM_DATA
].count
&& xbm_file_p (kw
[XBM_DATA
].value
))
2482 /* In-memory XBM file. */
2483 if (kw
[XBM_WIDTH
].count
|| kw
[XBM_HEIGHT
].count
|| kw
[XBM_FILE
].count
)
2491 /* Entries for `:width', `:height' and `:data' must be present. */
2492 if (!kw
[XBM_WIDTH
].count
2493 || !kw
[XBM_HEIGHT
].count
2494 || !kw
[XBM_DATA
].count
)
2497 data
= kw
[XBM_DATA
].value
;
2498 width
= XFASTINT (kw
[XBM_WIDTH
].value
);
2499 height
= XFASTINT (kw
[XBM_HEIGHT
].value
);
2501 /* Check type of data, and width and height against contents of
2507 /* Number of elements of the vector must be >= height. */
2508 if (ASIZE (data
) < height
)
2511 /* Each string or bool-vector in data must be large enough
2512 for one line of the image. */
2513 for (i
= 0; i
< height
; ++i
)
2515 Lisp_Object elt
= AREF (data
, i
);
2520 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
)
2523 else if (BOOL_VECTOR_P (elt
))
2525 if (bool_vector_size (elt
) < width
)
2532 else if (STRINGP (data
))
2535 < (width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
* height
)
2538 else if (BOOL_VECTOR_P (data
))
2540 if (bool_vector_size (data
) / height
< width
)
2551 /* Scan a bitmap file. FP is the stream to read from. Value is
2552 either an enumerator from enum xbm_token, or a character for a
2553 single-character token, or 0 at end of file. If scanning an
2554 identifier, store the lexeme of the identifier in SVAL. If
2555 scanning a number, store its value in *IVAL. */
2558 xbm_scan (unsigned char **s
, unsigned char *end
, char *sval
, int *ival
)
2564 /* Skip white space. */
2565 while (*s
< end
&& (c
= *(*s
)++, c_isspace (c
)))
2570 else if (c_isdigit (c
))
2572 int value
= 0, digit
;
2574 if (c
== '0' && *s
< end
)
2577 if (c
== 'x' || c
== 'X')
2584 else if (c
>= 'a' && c
<= 'f')
2585 digit
= c
- 'a' + 10;
2586 else if (c
>= 'A' && c
<= 'F')
2587 digit
= c
- 'A' + 10;
2590 value
= 16 * value
+ digit
;
2593 else if (c_isdigit (c
))
2597 && (c
= *(*s
)++, c_isdigit (c
)))
2598 value
= 8 * value
+ c
- '0';
2605 && (c
= *(*s
)++, c_isdigit (c
)))
2606 value
= 10 * value
+ c
- '0';
2614 else if (c_isalpha (c
) || c
== '_')
2618 && (c
= *(*s
)++, (c_isalnum (c
) || c
== '_')))
2625 else if (c
== '/' && **s
== '*')
2627 /* C-style comment. */
2629 while (**s
&& (**s
!= '*' || *(*s
+ 1) != '/'))
2643 /* Create a Windows bitmap from X bitmap data. */
2645 w32_create_pixmap_from_bitmap_data (int width
, int height
, char *data
)
2647 static unsigned char swap_nibble
[16]
2648 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
2649 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
2650 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
2651 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
2653 unsigned char *bits
, *p
;
2656 w1
= (width
+ 7) / 8; /* nb of 8bits elt in X bitmap */
2657 w2
= ((width
+ 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
2658 bits
= alloca (height
* w2
);
2659 memset (bits
, 0, height
* w2
);
2660 for (i
= 0; i
< height
; i
++)
2663 for (j
= 0; j
< w1
; j
++)
2665 /* Bitswap XBM bytes to match how Windows does things. */
2666 unsigned char c
= *data
++;
2667 *p
++ = (unsigned char)((swap_nibble
[c
& 0xf] << 4)
2668 | (swap_nibble
[(c
>>4) & 0xf]));
2671 bmp
= CreateBitmap (width
, height
, 1, 1, (char *) bits
);
2677 convert_mono_to_color_image (struct frame
*f
, struct image
*img
,
2678 COLORREF foreground
, COLORREF background
)
2680 HDC hdc
, old_img_dc
, new_img_dc
;
2681 HGDIOBJ old_prev
, new_prev
;
2684 hdc
= get_frame_dc (f
);
2685 old_img_dc
= CreateCompatibleDC (hdc
);
2686 new_img_dc
= CreateCompatibleDC (hdc
);
2687 new_pixmap
= CreateCompatibleBitmap (hdc
, img
->width
, img
->height
);
2688 release_frame_dc (f
, hdc
);
2689 old_prev
= SelectObject (old_img_dc
, img
->pixmap
);
2690 new_prev
= SelectObject (new_img_dc
, new_pixmap
);
2691 /* Windows convention for mono bitmaps is black = background,
2692 white = foreground. */
2693 SetTextColor (new_img_dc
, background
);
2694 SetBkColor (new_img_dc
, foreground
);
2696 BitBlt (new_img_dc
, 0, 0, img
->width
, img
->height
, old_img_dc
,
2699 SelectObject (old_img_dc
, old_prev
);
2700 SelectObject (new_img_dc
, new_prev
);
2701 DeleteDC (old_img_dc
);
2702 DeleteDC (new_img_dc
);
2703 DeleteObject (img
->pixmap
);
2704 if (new_pixmap
== 0)
2705 fprintf (stderr
, "Failed to convert image to color.\n");
2707 img
->pixmap
= new_pixmap
;
2710 #define XBM_BIT_SHUFFLE(b) (~(b))
2714 #define XBM_BIT_SHUFFLE(b) (b)
2716 #endif /* HAVE_NTGUI */
2720 Create_Pixmap_From_Bitmap_Data (struct frame
*f
, struct image
*img
, char *data
,
2721 RGB_PIXEL_COLOR fg
, RGB_PIXEL_COLOR bg
,
2722 bool non_default_colors
)
2726 = w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
, data
);
2728 /* If colors were specified, transfer the bitmap to a color one. */
2729 if (non_default_colors
)
2730 convert_mono_to_color_image (f
, img
, fg
, bg
);
2732 #elif defined (HAVE_NS)
2733 img
->pixmap
= ns_image_from_XBM (data
, img
->width
, img
->height
, fg
, bg
);
2737 (x_check_image_size (0, img
->width
, img
->height
)
2738 ? XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f
),
2741 img
->width
, img
->height
,
2743 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)))
2745 #endif /* !HAVE_NTGUI && !HAVE_NS */
2750 /* Replacement for XReadBitmapFileData which isn't available under old
2751 X versions. CONTENTS is a pointer to a buffer to parse; END is the
2752 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
2753 the image. Return in *DATA the bitmap data allocated with xmalloc.
2754 Value is true if successful. DATA null means just test if
2755 CONTENTS looks like an in-memory XBM file. If INHIBIT_IMAGE_ERROR,
2756 inhibit the call to image_error when the image size is invalid (the
2757 bitmap remains unread). */
2760 xbm_read_bitmap_data (struct frame
*f
, unsigned char *contents
, unsigned char *end
,
2761 int *width
, int *height
, char **data
,
2762 bool inhibit_image_error
)
2764 unsigned char *s
= contents
;
2765 char buffer
[BUFSIZ
];
2768 int bytes_per_line
, i
, nbytes
;
2774 LA1 = xbm_scan (&s, end, buffer, &value)
2776 #define expect(TOKEN) \
2779 if (LA1 != (TOKEN)) \
2785 #define expect_ident(IDENT) \
2786 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
2791 *width
= *height
= -1;
2794 LA1
= xbm_scan (&s
, end
, buffer
, &value
);
2796 /* Parse defines for width, height and hot-spots. */
2800 expect_ident ("define");
2801 expect (XBM_TK_IDENT
);
2803 if (LA1
== XBM_TK_NUMBER
)
2805 char *q
= strrchr (buffer
, '_');
2806 q
= q
? q
+ 1 : buffer
;
2807 if (strcmp (q
, "width") == 0)
2809 else if (strcmp (q
, "height") == 0)
2812 expect (XBM_TK_NUMBER
);
2815 if (!check_image_size (f
, *width
, *height
))
2817 if (!inhibit_image_error
)
2818 image_size_error ();
2821 else if (data
== NULL
)
2824 /* Parse bits. Must start with `static'. */
2825 expect_ident ("static");
2826 if (LA1
== XBM_TK_IDENT
)
2828 if (strcmp (buffer
, "unsigned") == 0)
2831 expect_ident ("char");
2833 else if (strcmp (buffer
, "short") == 0)
2837 if (*width
% 16 && *width
% 16 < 9)
2840 else if (strcmp (buffer
, "char") == 0)
2848 expect (XBM_TK_IDENT
);
2854 if (! x_check_image_size (0, *width
, *height
))
2856 if (!inhibit_image_error
)
2857 image_error ("Image too large (%dx%d)",
2858 make_number (*width
), make_number (*height
));
2861 bytes_per_line
= (*width
+ 7) / 8 + padding_p
;
2862 nbytes
= bytes_per_line
* *height
;
2863 p
= *data
= xmalloc (nbytes
);
2867 for (i
= 0; i
< nbytes
; i
+= 2)
2870 expect (XBM_TK_NUMBER
);
2872 *p
++ = XBM_BIT_SHUFFLE (val
);
2873 if (!padding_p
|| ((i
+ 2) % bytes_per_line
))
2874 *p
++ = XBM_BIT_SHUFFLE (value
>> 8);
2876 if (LA1
== ',' || LA1
== '}')
2884 for (i
= 0; i
< nbytes
; ++i
)
2887 expect (XBM_TK_NUMBER
);
2889 *p
++ = XBM_BIT_SHUFFLE (val
);
2891 if (LA1
== ',' || LA1
== '}')
2916 /* Load XBM image IMG which will be displayed on frame F from buffer
2917 CONTENTS. END is the end of the buffer. Value is true if
2921 xbm_load_image (struct frame
*f
, struct image
*img
, unsigned char *contents
,
2928 rc
= xbm_read_bitmap_data (f
, contents
, end
, &img
->width
, &img
->height
,
2932 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
2933 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
2934 bool non_default_colors
= 0;
2937 eassert (img
->width
> 0 && img
->height
> 0);
2939 /* Get foreground and background colors, maybe allocate colors. */
2940 value
= image_spec_value (img
->spec
, QCforeground
, NULL
);
2943 foreground
= x_alloc_image_color (f
, img
, value
, foreground
);
2944 non_default_colors
= 1;
2946 value
= image_spec_value (img
->spec
, QCbackground
, NULL
);
2949 background
= x_alloc_image_color (f
, img
, value
, background
);
2950 img
->background
= background
;
2951 img
->background_valid
= 1;
2952 non_default_colors
= 1;
2955 Create_Pixmap_From_Bitmap_Data (f
, img
, data
,
2956 foreground
, background
,
2957 non_default_colors
);
2960 if (img
->pixmap
== NO_PIXMAP
)
2962 x_clear_image (f
, img
);
2963 image_error ("Unable to create X pixmap for `%s'", img
->spec
);
2969 image_error ("Error loading XBM image `%s'", img
->spec
);
2975 /* Value is true if DATA looks like an in-memory XBM file. */
2978 xbm_file_p (Lisp_Object data
)
2981 return (STRINGP (data
)
2982 && xbm_read_bitmap_data (NULL
, SDATA (data
),
2983 (SDATA (data
) + SBYTES (data
)),
2988 /* Fill image IMG which is used on frame F with pixmap data. Value is
2989 true if successful. */
2992 xbm_load (struct frame
*f
, struct image
*img
)
2995 Lisp_Object file_name
;
2997 eassert (xbm_image_p (img
->spec
));
2999 /* If IMG->spec specifies a file name, create a non-file spec from it. */
3000 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
3001 if (STRINGP (file_name
))
3004 Lisp_Object file
= x_find_image_fd (file_name
, &fd
);
3005 if (!STRINGP (file
))
3007 image_error ("Cannot find image file `%s'", file_name
);
3012 unsigned char *contents
= slurp_file (fd
, &size
);
3013 if (contents
== NULL
)
3015 image_error ("Error loading XBM image `%s'", file
);
3019 success_p
= xbm_load_image (f
, img
, contents
, contents
+ size
);
3024 struct image_keyword fmt
[XBM_LAST
];
3026 unsigned long foreground
= FRAME_FOREGROUND_PIXEL (f
);
3027 unsigned long background
= FRAME_BACKGROUND_PIXEL (f
);
3028 bool non_default_colors
= 0;
3031 bool in_memory_file_p
= 0;
3033 /* See if data looks like an in-memory XBM file. */
3034 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
3035 in_memory_file_p
= xbm_file_p (data
);
3037 /* Parse the image specification. */
3038 memcpy (fmt
, xbm_format
, sizeof fmt
);
3039 parsed_p
= parse_image_spec (img
->spec
, fmt
, XBM_LAST
, Qxbm
);
3042 /* Get specified width, and height. */
3043 if (!in_memory_file_p
)
3045 img
->width
= XFASTINT (fmt
[XBM_WIDTH
].value
);
3046 img
->height
= XFASTINT (fmt
[XBM_HEIGHT
].value
);
3047 eassert (img
->width
> 0 && img
->height
> 0);
3048 if (!check_image_size (f
, img
->width
, img
->height
))
3050 image_size_error ();
3055 /* Get foreground and background colors, maybe allocate colors. */
3056 if (fmt
[XBM_FOREGROUND
].count
3057 && STRINGP (fmt
[XBM_FOREGROUND
].value
))
3059 foreground
= x_alloc_image_color (f
, img
, fmt
[XBM_FOREGROUND
].value
,
3061 non_default_colors
= 1;
3064 if (fmt
[XBM_BACKGROUND
].count
3065 && STRINGP (fmt
[XBM_BACKGROUND
].value
))
3067 background
= x_alloc_image_color (f
, img
, fmt
[XBM_BACKGROUND
].value
,
3069 non_default_colors
= 1;
3072 if (in_memory_file_p
)
3073 success_p
= xbm_load_image (f
, img
, SDATA (data
),
3084 int nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
3086 SAFE_NALLOCA (bits
, nbytes
, img
->height
);
3088 for (i
= 0; i
< img
->height
; ++i
, p
+= nbytes
)
3090 Lisp_Object line
= AREF (data
, i
);
3092 memcpy (p
, SDATA (line
), nbytes
);
3094 memcpy (p
, bool_vector_data (line
), nbytes
);
3097 else if (STRINGP (data
))
3098 bits
= SSDATA (data
);
3100 bits
= (char *) bool_vector_data (data
);
3106 /* Windows mono bitmaps are reversed compared with X. */
3107 invertedBits
= bits
;
3108 nbytes
= (img
->width
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
3109 SAFE_NALLOCA (bits
, nbytes
, img
->height
);
3110 for (i
= 0; i
< nbytes
; i
++)
3111 bits
[i
] = XBM_BIT_SHUFFLE (invertedBits
[i
]);
3114 /* Create the pixmap. */
3116 if (x_check_image_size (0, img
->width
, img
->height
))
3117 Create_Pixmap_From_Bitmap_Data (f
, img
, bits
,
3118 foreground
, background
,
3119 non_default_colors
);
3121 img
->pixmap
= NO_PIXMAP
;
3127 image_error ("Unable to create pixmap for XBM image `%s'",
3129 x_clear_image (f
, img
);
3141 /***********************************************************************
3143 ***********************************************************************/
3145 #if defined (HAVE_XPM) || defined (HAVE_NS)
3147 static bool xpm_image_p (Lisp_Object object
);
3148 static bool xpm_load (struct frame
*f
, struct image
*img
);
3150 #endif /* HAVE_XPM || HAVE_NS */
3154 /* Indicate to xpm.h that we don't have Xlib. */
3156 /* simx.h in xpm defines XColor and XImage differently than Emacs. */
3157 /* It also defines Display the same way as Emacs, but gcc 3.3 still barfs. */
3158 #define XColor xpm_XColor
3159 #define XImage xpm_XImage
3160 #define Display xpm_Display
3161 #define PIXEL_ALREADY_TYPEDEFED
3162 #include "X11/xpm.h"
3167 #undef PIXEL_ALREADY_TYPEDEFED
3169 #include "X11/xpm.h"
3170 #endif /* HAVE_NTGUI */
3171 #endif /* HAVE_XPM */
3173 #if defined (HAVE_XPM) || defined (HAVE_NS)
3175 /* Indices of image specification fields in xpm_format, below. */
3177 enum xpm_keyword_index
3193 /* Vector of image_keyword structures describing the format
3194 of valid XPM image specifications. */
3196 static const struct image_keyword xpm_format
[XPM_LAST
] =
3198 {":type", IMAGE_SYMBOL_VALUE
, 1},
3199 {":file", IMAGE_STRING_VALUE
, 0},
3200 {":data", IMAGE_STRING_VALUE
, 0},
3201 {":ascent", IMAGE_ASCENT_VALUE
, 0},
3202 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
3203 {":relief", IMAGE_INTEGER_VALUE
, 0},
3204 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3205 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3206 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3207 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
3208 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
3211 #if defined HAVE_NTGUI && defined WINDOWSNT
3212 static bool init_xpm_functions (void);
3214 #define init_xpm_functions NULL
3217 /* Structure describing the image type XPM. */
3219 static struct image_type xpm_type
=
3221 SYMBOL_INDEX (Qxpm
),
3229 #ifdef HAVE_X_WINDOWS
3231 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
3232 functions for allocating image colors. Our own functions handle
3233 color allocation failures more gracefully than the ones on the XPM
3237 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
3238 #define ALLOC_XPM_COLORS
3240 #endif /* USE_CAIRO */
3241 #endif /* HAVE_X_WINDOWS */
3243 #ifdef ALLOC_XPM_COLORS
3245 static struct xpm_cached_color
*xpm_cache_color (struct frame
*, char *,
3248 /* An entry in a hash table used to cache color definitions of named
3249 colors. This cache is necessary to speed up XPM image loading in
3250 case we do color allocations ourselves. Without it, we would need
3251 a call to XParseColor per pixel in the image.
3253 FIXME Now that we're using x_parse_color and its cache, reevaluate
3254 the need for this caching layer. */
3256 struct xpm_cached_color
3258 /* Next in collision chain. */
3259 struct xpm_cached_color
*next
;
3261 /* Color definition (RGB and pixel color). */
3265 char name
[FLEXIBLE_ARRAY_MEMBER
];
3268 /* The hash table used for the color cache, and its bucket vector
3271 #define XPM_COLOR_CACHE_BUCKETS 1001
3272 static struct xpm_cached_color
**xpm_color_cache
;
3274 /* Initialize the color cache. */
3277 xpm_init_color_cache (struct frame
*f
, XpmAttributes
*attrs
)
3279 size_t nbytes
= XPM_COLOR_CACHE_BUCKETS
* sizeof *xpm_color_cache
;
3280 xpm_color_cache
= xzalloc (nbytes
);
3281 init_color_table ();
3283 if (attrs
->valuemask
& XpmColorSymbols
)
3288 for (i
= 0; i
< attrs
->numsymbols
; ++i
)
3289 if (x_parse_color (f
, attrs
->colorsymbols
[i
].value
, &color
))
3291 color
.pixel
= lookup_rgb_color (f
, color
.red
, color
.green
,
3293 xpm_cache_color (f
, attrs
->colorsymbols
[i
].name
, &color
, -1);
3298 /* Free the color cache. */
3301 xpm_free_color_cache (void)
3303 struct xpm_cached_color
*p
, *next
;
3306 for (i
= 0; i
< XPM_COLOR_CACHE_BUCKETS
; ++i
)
3307 for (p
= xpm_color_cache
[i
]; p
; p
= next
)
3313 xfree (xpm_color_cache
);
3314 xpm_color_cache
= NULL
;
3315 free_color_table ();
3318 /* Return the bucket index for color named COLOR_NAME in the color
3322 xpm_color_bucket (char *color_name
)
3324 EMACS_UINT hash
= hash_string (color_name
, strlen (color_name
));
3325 return hash
% XPM_COLOR_CACHE_BUCKETS
;
3329 /* On frame F, cache values COLOR for color with name COLOR_NAME.
3330 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
3333 static struct xpm_cached_color
*
3334 xpm_cache_color (struct frame
*f
, char *color_name
, XColor
*color
, int bucket
)
3337 struct xpm_cached_color
*p
;
3340 bucket
= xpm_color_bucket (color_name
);
3342 nbytes
= offsetof (struct xpm_cached_color
, name
) + strlen (color_name
) + 1;
3343 p
= xmalloc (nbytes
);
3344 strcpy (p
->name
, color_name
);
3346 p
->next
= xpm_color_cache
[bucket
];
3347 xpm_color_cache
[bucket
] = p
;
3351 /* Look up color COLOR_NAME for frame F in the color cache. If found,
3352 return the cached definition in *COLOR. Otherwise, make a new
3353 entry in the cache and allocate the color. Value is false if color
3354 allocation failed. */
3357 xpm_lookup_color (struct frame
*f
, char *color_name
, XColor
*color
)
3359 struct xpm_cached_color
*p
;
3360 int h
= xpm_color_bucket (color_name
);
3362 for (p
= xpm_color_cache
[h
]; p
; p
= p
->next
)
3363 if (strcmp (p
->name
, color_name
) == 0)
3368 else if (x_parse_color (f
, color_name
, color
))
3370 color
->pixel
= lookup_rgb_color (f
, color
->red
, color
->green
,
3372 p
= xpm_cache_color (f
, color_name
, color
, h
);
3374 /* You get `opaque' at least from ImageMagick converting pbm to xpm
3375 with transparency, and it's useful. */
3376 else if (strcmp ("opaque", color_name
) == 0)
3378 memset (color
, 0, sizeof (XColor
)); /* Is this necessary/correct? */
3379 color
->pixel
= FRAME_FOREGROUND_PIXEL (f
);
3380 p
= xpm_cache_color (f
, color_name
, color
, h
);
3387 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
3388 CLOSURE is a pointer to the frame on which we allocate the
3389 color. Return in *COLOR the allocated color. Value is non-zero
3393 xpm_alloc_color (Display
*dpy
, Colormap cmap
, char *color_name
, XColor
*color
,
3396 return xpm_lookup_color (closure
, color_name
, color
);
3400 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
3401 is a pointer to the frame on which we allocate the color. Value is
3402 non-zero if successful. */
3405 xpm_free_colors (Display
*dpy
, Colormap cmap
, Pixel
*pixels
, int npixels
, void *closure
)
3410 #endif /* ALLOC_XPM_COLORS */
3415 /* XPM library details. */
3417 DEF_DLL_FN (void, XpmFreeAttributes
, (XpmAttributes
*));
3418 DEF_DLL_FN (int, XpmCreateImageFromBuffer
,
3419 (Display
*, char *, xpm_XImage
**,
3420 xpm_XImage
**, XpmAttributes
*));
3421 DEF_DLL_FN (int, XpmReadFileToImage
,
3422 (Display
*, char *, xpm_XImage
**,
3423 xpm_XImage
**, XpmAttributes
*));
3424 DEF_DLL_FN (void, XImageFree
, (xpm_XImage
*));
3427 init_xpm_functions (void)
3431 if (!(library
= w32_delayed_load (Qxpm
)))
3434 LOAD_DLL_FN (library
, XpmFreeAttributes
);
3435 LOAD_DLL_FN (library
, XpmCreateImageFromBuffer
);
3436 LOAD_DLL_FN (library
, XpmReadFileToImage
);
3437 LOAD_DLL_FN (library
, XImageFree
);
3442 # undef XpmCreateImageFromBuffer
3443 # undef XpmFreeAttributes
3444 # undef XpmReadFileToImage
3446 # define XImageFree fn_XImageFree
3447 # define XpmCreateImageFromBuffer fn_XpmCreateImageFromBuffer
3448 # define XpmFreeAttributes fn_XpmFreeAttributes
3449 # define XpmReadFileToImage fn_XpmReadFileToImage
3451 #endif /* WINDOWSNT */
3453 /* Value is true if COLOR_SYMBOLS is a valid color symbols list
3454 for XPM images. Such a list must consist of conses whose car and
3458 xpm_valid_color_symbols_p (Lisp_Object color_symbols
)
3460 while (CONSP (color_symbols
))
3462 Lisp_Object sym
= XCAR (color_symbols
);
3464 || !STRINGP (XCAR (sym
))
3465 || !STRINGP (XCDR (sym
)))
3467 color_symbols
= XCDR (color_symbols
);
3470 return NILP (color_symbols
);
3474 /* Value is true if OBJECT is a valid XPM image specification. */
3477 xpm_image_p (Lisp_Object object
)
3479 struct image_keyword fmt
[XPM_LAST
];
3480 memcpy (fmt
, xpm_format
, sizeof fmt
);
3481 return (parse_image_spec (object
, fmt
, XPM_LAST
, Qxpm
)
3482 /* Either `:file' or `:data' must be present. */
3483 && fmt
[XPM_FILE
].count
+ fmt
[XPM_DATA
].count
== 1
3484 /* Either no `:color-symbols' or it's a list of conses
3485 whose car and cdr are strings. */
3486 && (fmt
[XPM_COLOR_SYMBOLS
].count
== 0
3487 || xpm_valid_color_symbols_p (fmt
[XPM_COLOR_SYMBOLS
].value
)));
3490 #endif /* HAVE_XPM || HAVE_NS */
3492 #if defined HAVE_XPM && defined HAVE_X_WINDOWS && !defined USE_GTK
3494 x_create_bitmap_from_xpm_data (struct frame
*f
, const char **bits
)
3496 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
3499 XpmAttributes attrs
;
3500 Pixmap bitmap
, mask
;
3502 memset (&attrs
, 0, sizeof attrs
);
3504 attrs
.visual
= FRAME_X_VISUAL (f
);
3505 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3506 attrs
.valuemask
|= XpmVisual
;
3507 attrs
.valuemask
|= XpmColormap
;
3509 #ifdef ALLOC_XPM_COLORS
3510 attrs
.color_closure
= f
;
3511 attrs
.alloc_color
= xpm_alloc_color
;
3512 attrs
.free_colors
= xpm_free_colors
;
3513 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
3514 xpm_init_color_cache (f
, &attrs
);
3517 rc
= XpmCreatePixmapFromData (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3518 (char **) bits
, &bitmap
, &mask
, &attrs
);
3519 if (rc
!= XpmSuccess
)
3521 XpmFreeAttributes (&attrs
);
3525 id
= x_allocate_bitmap_record (f
);
3526 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
3527 dpyinfo
->bitmaps
[id
- 1].have_mask
= true;
3528 dpyinfo
->bitmaps
[id
- 1].mask
= mask
;
3529 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
3530 dpyinfo
->bitmaps
[id
- 1].height
= attrs
.height
;
3531 dpyinfo
->bitmaps
[id
- 1].width
= attrs
.width
;
3532 dpyinfo
->bitmaps
[id
- 1].depth
= attrs
.depth
;
3533 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
3535 #ifdef ALLOC_XPM_COLORS
3536 xpm_free_color_cache ();
3538 XpmFreeAttributes (&attrs
);
3541 #endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */
3543 /* Load image IMG which will be displayed on frame F. Value is
3544 true if successful. */
3549 xpm_load (struct frame
*f
, struct image
*img
)
3552 XpmAttributes attrs
;
3553 Lisp_Object specified_file
, color_symbols
;
3558 xpm_XImage
* xpm_image
= NULL
, * xpm_mask
= NULL
;
3559 #endif /* HAVE_NTGUI */
3561 /* Configure the XPM lib. Use the visual of frame F. Allocate
3562 close colors. Return colors allocated. */
3563 memset (&attrs
, 0, sizeof attrs
);
3566 attrs
.visual
= FRAME_X_VISUAL (f
);
3567 attrs
.colormap
= FRAME_X_COLORMAP (f
);
3568 attrs
.valuemask
|= XpmVisual
;
3569 attrs
.valuemask
|= XpmColormap
;
3570 #endif /* HAVE_NTGUI */
3572 #ifdef ALLOC_XPM_COLORS
3573 /* Allocate colors with our own functions which handle
3574 failing color allocation more gracefully. */
3575 attrs
.color_closure
= f
;
3576 attrs
.alloc_color
= xpm_alloc_color
;
3577 attrs
.free_colors
= xpm_free_colors
;
3578 attrs
.valuemask
|= XpmAllocColor
| XpmFreeColors
| XpmColorClosure
;
3579 #else /* not ALLOC_XPM_COLORS */
3580 /* Let the XPM lib allocate colors. */
3581 attrs
.valuemask
|= XpmReturnAllocPixels
;
3582 #ifdef XpmAllocCloseColors
3583 attrs
.alloc_close_colors
= 1;
3584 attrs
.valuemask
|= XpmAllocCloseColors
;
3585 #else /* not XpmAllocCloseColors */
3586 attrs
.closeness
= 600;
3587 attrs
.valuemask
|= XpmCloseness
;
3588 #endif /* not XpmAllocCloseColors */
3589 #endif /* ALLOC_XPM_COLORS */
3591 /* If image specification contains symbolic color definitions, add
3592 these to `attrs'. */
3593 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
3594 if (CONSP (color_symbols
))
3597 XpmColorSymbol
*xpm_syms
;
3600 attrs
.valuemask
|= XpmColorSymbols
;
3602 /* Count number of symbols. */
3603 attrs
.numsymbols
= 0;
3604 for (tail
= color_symbols
; CONSP (tail
); tail
= XCDR (tail
))
3607 /* Allocate an XpmColorSymbol array. */
3608 SAFE_NALLOCA (xpm_syms
, 1, attrs
.numsymbols
);
3609 size
= attrs
.numsymbols
* sizeof *xpm_syms
;
3610 memset (xpm_syms
, 0, size
);
3611 attrs
.colorsymbols
= xpm_syms
;
3613 /* Fill the color symbol array. */
3614 for (tail
= color_symbols
, i
= 0;
3616 ++i
, tail
= XCDR (tail
))
3620 char *empty_string
= (char *) "";
3622 if (!CONSP (XCAR (tail
)))
3624 xpm_syms
[i
].name
= empty_string
;
3625 xpm_syms
[i
].value
= empty_string
;
3628 name
= XCAR (XCAR (tail
));
3629 color
= XCDR (XCAR (tail
));
3631 SAFE_ALLOCA_STRING (xpm_syms
[i
].name
, name
);
3633 xpm_syms
[i
].name
= empty_string
;
3634 if (STRINGP (color
))
3635 SAFE_ALLOCA_STRING (xpm_syms
[i
].value
, color
);
3637 xpm_syms
[i
].value
= empty_string
;
3641 /* Create a pixmap for the image, either from a file, or from a
3642 string buffer containing data in the same format as an XPM file. */
3643 #ifdef ALLOC_XPM_COLORS
3644 xpm_init_color_cache (f
, &attrs
);
3647 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
3651 HDC frame_dc
= get_frame_dc (f
);
3652 hdc
= CreateCompatibleDC (frame_dc
);
3653 release_frame_dc (f
, frame_dc
);
3655 #endif /* HAVE_NTGUI */
3657 if (STRINGP (specified_file
))
3659 Lisp_Object file
= x_find_image_file (specified_file
);
3660 if (!STRINGP (file
))
3662 image_error ("Cannot find image file `%s'", specified_file
);
3663 #ifdef ALLOC_XPM_COLORS
3664 xpm_free_color_cache ();
3670 file
= ENCODE_FILE (file
);
3673 /* FILE is encoded in UTF-8, but image libraries on Windows
3674 support neither UTF-8 nor UTF-16 encoded file names. So we
3675 need to re-encode it in ANSI. */
3676 file
= ansi_encode_filename (file
);
3678 /* XpmReadFileToPixmap is not available in the Windows port of
3679 libxpm. But XpmReadFileToImage almost does what we want. */
3680 rc
= XpmReadFileToImage (&hdc
, SDATA (file
),
3681 &xpm_image
, &xpm_mask
,
3684 rc
= XpmReadFileToImage (FRAME_X_DISPLAY (f
), SSDATA (file
),
3685 &img
->ximg
, &img
->mask_img
,
3687 #endif /* HAVE_NTGUI */
3691 Lisp_Object buffer
= image_spec_value (img
->spec
, QCdata
, NULL
);
3692 if (!STRINGP (buffer
))
3694 image_error ("Invalid image data `%s'", buffer
);
3695 #ifdef ALLOC_XPM_COLORS
3696 xpm_free_color_cache ();
3702 /* XpmCreatePixmapFromBuffer is not available in the Windows port
3703 of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
3704 rc
= XpmCreateImageFromBuffer (&hdc
, SDATA (buffer
),
3705 &xpm_image
, &xpm_mask
,
3708 rc
= XpmCreateImageFromBuffer (FRAME_X_DISPLAY (f
), SSDATA (buffer
),
3709 &img
->ximg
, &img
->mask_img
,
3711 #endif /* HAVE_NTGUI */
3715 // Load very specific Xpm:s.
3716 if (rc
== XpmSuccess
3717 && img
->ximg
->format
== ZPixmap
3718 && img
->ximg
->bits_per_pixel
== 32
3719 && (! img
->mask_img
|| img
->mask_img
->bits_per_pixel
== 1))
3721 int width
= img
->ximg
->width
;
3722 int height
= img
->ximg
->height
;
3723 unsigned char *data
= (unsigned char *) xmalloc (width
*height
*4);
3725 uint32_t *od
= (uint32_t *)data
;
3726 uint32_t *id
= (uint32_t *)img
->ximg
->data
;
3727 char *mid
= img
->mask_img
? img
->mask_img
->data
: 0;
3728 uint32_t bgcolor
= get_spec_bg_or_alpha_as_argb (img
, f
);
3730 for (i
= 0; i
< height
; ++i
)
3733 for (k
= 0; k
< width
; ++k
)
3735 int idx
= i
* img
->ximg
->bytes_per_line
/4 + k
;
3736 int maskidx
= mid
? i
* img
->mask_img
->bytes_per_line
+ k
/8 : 0;
3737 int mask
= mid
? mid
[maskidx
] & (1 << (k
% 8)) : 1;
3739 if (mask
) od
[idx
] = id
[idx
] + 0xff000000; // ff => full alpha
3740 else od
[idx
] = bgcolor
;
3744 create_cairo_image_surface (img
, data
, width
, height
);
3748 rc
= XpmFileInvalid
;
3749 x_clear_image (f
, img
);
3752 #ifdef HAVE_X_WINDOWS
3753 if (rc
== XpmSuccess
)
3755 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3756 img
->ximg
->width
, img
->ximg
->height
,
3758 if (img
->pixmap
== NO_PIXMAP
)
3760 x_clear_image (f
, img
);
3763 else if (img
->mask_img
)
3765 img
->mask
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
3766 img
->mask_img
->width
,
3767 img
->mask_img
->height
,
3768 img
->mask_img
->depth
);
3769 if (img
->mask
== NO_PIXMAP
)
3771 x_clear_image (f
, img
);
3777 #endif /* ! USE_CAIRO */
3779 if (rc
== XpmSuccess
)
3781 #if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS)
3782 img
->colors
= colors_in_color_table (&img
->ncolors
);
3783 #else /* not ALLOC_XPM_COLORS */
3787 /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
3788 plus some duplicate attributes. */
3789 if (xpm_image
&& xpm_image
->bitmap
)
3791 img
->pixmap
= xpm_image
->bitmap
;
3792 /* XImageFree in libXpm frees XImage struct without destroying
3793 the bitmap, which is what we want. */
3794 XImageFree (xpm_image
);
3796 if (xpm_mask
&& xpm_mask
->bitmap
)
3798 /* The mask appears to be inverted compared with what we expect.
3799 TODO: invert our expectations. See other places where we
3800 have to invert bits because our idea of masks is backwards. */
3802 old_obj
= SelectObject (hdc
, xpm_mask
->bitmap
);
3804 PatBlt (hdc
, 0, 0, xpm_mask
->width
, xpm_mask
->height
, DSTINVERT
);
3805 SelectObject (hdc
, old_obj
);
3807 img
->mask
= xpm_mask
->bitmap
;
3808 XImageFree (xpm_mask
);
3813 #endif /* HAVE_NTGUI */
3815 /* Remember allocated colors. */
3816 img
->colors
= xnmalloc (attrs
.nalloc_pixels
, sizeof *img
->colors
);
3817 img
->ncolors
= attrs
.nalloc_pixels
;
3818 for (i
= 0; i
< attrs
.nalloc_pixels
; ++i
)
3820 img
->colors
[i
] = attrs
.alloc_pixels
[i
];
3821 #ifdef DEBUG_X_COLORS
3822 register_color (img
->colors
[i
]);
3825 #endif /* not ALLOC_XPM_COLORS */
3827 img
->width
= attrs
.width
;
3828 img
->height
= attrs
.height
;
3829 eassert (img
->width
> 0 && img
->height
> 0);
3831 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
3832 XpmFreeAttributes (&attrs
);
3834 #ifdef HAVE_X_WINDOWS
3835 /* Maybe fill in the background field while we have ximg handy. */
3836 IMAGE_BACKGROUND (img
, f
, img
->ximg
);
3838 /* Fill in the background_transparent field while we have the
3840 image_background_transparent (img
, f
, img
->mask_img
);
3847 #endif /* HAVE_NTGUI */
3852 image_error ("Error opening XPM file (%s)", img
->spec
);
3855 case XpmFileInvalid
:
3856 image_error ("Invalid XPM file (%s)", img
->spec
);
3860 image_error ("Out of memory (%s)", img
->spec
);
3863 case XpmColorFailed
:
3864 image_error ("Color allocation error (%s)", img
->spec
);
3868 image_error ("Unknown error (%s)", img
->spec
);
3873 #ifdef ALLOC_XPM_COLORS
3874 xpm_free_color_cache ();
3877 return rc
== XpmSuccess
;
3880 #endif /* HAVE_XPM */
3882 #if defined (HAVE_NS) && !defined (HAVE_XPM)
3884 /* XPM support functions for NS where libxpm is not available.
3885 Only XPM version 3 (without any extensions) is supported. */
3887 static void xpm_put_color_table_v (Lisp_Object
, const unsigned char *,
3889 static Lisp_Object
xpm_get_color_table_v (Lisp_Object
,
3890 const unsigned char *, int);
3891 static void xpm_put_color_table_h (Lisp_Object
, const unsigned char *,
3893 static Lisp_Object
xpm_get_color_table_h (Lisp_Object
,
3894 const unsigned char *, int);
3896 /* Tokens returned from xpm_scan. */
3905 /* Scan an XPM data and return a character (< 256) or a token defined
3906 by enum xpm_token above. *S and END are the start (inclusive) and
3907 the end (exclusive) addresses of the data, respectively. Advance
3908 *S while scanning. If token is either XPM_TK_IDENT or
3909 XPM_TK_STRING, *BEG and *LEN are set to the start address and the
3910 length of the corresponding token, respectively. */
3913 xpm_scan (const unsigned char **s
,
3914 const unsigned char *end
,
3915 const unsigned char **beg
,
3922 /* Skip white-space. */
3923 while (*s
< end
&& (c
= *(*s
)++, c_isspace (c
)))
3926 /* gnus-pointer.xpm uses '-' in its identifier.
3927 sb-dir-plus.xpm uses '+' in its identifier. */
3928 if (c_isalpha (c
) || c
== '_' || c
== '-' || c
== '+')
3932 && (c
= **s
, c_isalnum (c
)
3933 || c
== '_' || c
== '-' || c
== '+'))
3936 return XPM_TK_IDENT
;
3941 while (*s
< end
&& **s
!= '"')
3946 return XPM_TK_STRING
;
3950 if (*s
< end
&& **s
== '*')
3952 /* C-style comment. */
3956 while (*s
< end
&& *(*s
)++ != '*')
3959 while (*s
< end
&& **s
!= '/');
3973 /* Functions for color table lookup in XPM data. A key is a string
3974 specifying the color of each pixel in XPM data. A value is either
3975 an integer that specifies a pixel color, Qt that specifies
3976 transparency, or Qnil for the unspecified color. If the length of
3977 the key string is one, a vector is used as a table. Otherwise, a
3978 hash table is used. */
3981 xpm_make_color_table_v (void (**put_func
) (Lisp_Object
,
3982 const unsigned char *,
3985 Lisp_Object (**get_func
) (Lisp_Object
,
3986 const unsigned char *,
3989 *put_func
= xpm_put_color_table_v
;
3990 *get_func
= xpm_get_color_table_v
;
3991 return Fmake_vector (make_number (256), Qnil
);
3995 xpm_put_color_table_v (Lisp_Object color_table
,
3996 const unsigned char *chars_start
,
4000 ASET (color_table
, *chars_start
, color
);
4004 xpm_get_color_table_v (Lisp_Object color_table
,
4005 const unsigned char *chars_start
,
4008 return AREF (color_table
, *chars_start
);
4012 xpm_make_color_table_h (void (**put_func
) (Lisp_Object
,
4013 const unsigned char *,
4016 Lisp_Object (**get_func
) (Lisp_Object
,
4017 const unsigned char *,
4020 *put_func
= xpm_put_color_table_h
;
4021 *get_func
= xpm_get_color_table_h
;
4022 return make_hash_table (hashtest_equal
, make_number (DEFAULT_HASH_SIZE
),
4023 make_float (DEFAULT_REHASH_SIZE
),
4024 make_float (DEFAULT_REHASH_THRESHOLD
),
4029 xpm_put_color_table_h (Lisp_Object color_table
,
4030 const unsigned char *chars_start
,
4034 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
4035 EMACS_UINT hash_code
;
4036 Lisp_Object chars
= make_unibyte_string (chars_start
, chars_len
);
4038 hash_lookup (table
, chars
, &hash_code
);
4039 hash_put (table
, chars
, color
, hash_code
);
4043 xpm_get_color_table_h (Lisp_Object color_table
,
4044 const unsigned char *chars_start
,
4047 struct Lisp_Hash_Table
*table
= XHASH_TABLE (color_table
);
4049 hash_lookup (table
, make_unibyte_string (chars_start
, chars_len
), NULL
);
4051 return i
>= 0 ? HASH_VALUE (table
, i
) : Qnil
;
4054 enum xpm_color_key
{
4062 static const char xpm_color_key_strings
[][4] = {"s", "m", "g4", "g", "c"};
4065 xpm_str_to_color_key (const char *s
)
4069 for (i
= 0; i
< ARRAYELTS (xpm_color_key_strings
); i
++)
4070 if (strcmp (xpm_color_key_strings
[i
], s
) == 0)
4076 xpm_load_image (struct frame
*f
,
4078 const unsigned char *contents
,
4079 const unsigned char *end
)
4081 const unsigned char *s
= contents
, *beg
, *str
;
4082 unsigned char buffer
[BUFSIZ
];
4083 int width
, height
, x
, y
;
4084 int num_colors
, chars_per_pixel
;
4087 void (*put_color_table
) (Lisp_Object
, const unsigned char *, int, Lisp_Object
);
4088 Lisp_Object (*get_color_table
) (Lisp_Object
, const unsigned char *, int);
4089 Lisp_Object frame
, color_symbols
, color_table
;
4091 bool have_mask
= false;
4092 XImagePtr ximg
= NULL
, mask_img
= NULL
;
4095 LA1 = xpm_scan (&s, end, &beg, &len)
4097 #define expect(TOKEN) \
4100 if (LA1 != (TOKEN)) \
4106 #define expect_ident(IDENT) \
4107 if (LA1 == XPM_TK_IDENT \
4108 && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
4113 if (!(end
- s
>= 9 && memcmp (s
, "/* XPM */", 9) == 0))
4117 expect_ident ("static");
4118 expect_ident ("char");
4120 expect (XPM_TK_IDENT
);
4125 expect (XPM_TK_STRING
);
4128 memcpy (buffer
, beg
, len
);
4130 if (sscanf (buffer
, "%d %d %d %d", &width
, &height
,
4131 &num_colors
, &chars_per_pixel
) != 4
4132 || width
<= 0 || height
<= 0
4133 || num_colors
<= 0 || chars_per_pixel
<= 0)
4136 if (!check_image_size (f
, width
, height
))
4138 image_size_error ();
4142 if (!image_create_x_image_and_pixmap (f
, img
, width
, height
, 0, &ximg
, 0)
4144 || !image_create_x_image_and_pixmap (f
, img
, width
, height
, 1,
4149 image_error ("Image too large");
4155 XSETFRAME (frame
, f
);
4156 if (!NILP (Fxw_display_color_p (frame
)))
4157 best_key
= XPM_COLOR_KEY_C
;
4158 else if (!NILP (Fx_display_grayscale_p (frame
)))
4159 best_key
= (XFASTINT (Fx_display_planes (frame
)) > 2
4160 ? XPM_COLOR_KEY_G
: XPM_COLOR_KEY_G4
);
4162 best_key
= XPM_COLOR_KEY_M
;
4164 color_symbols
= image_spec_value (img
->spec
, QCcolor_symbols
, NULL
);
4165 if (chars_per_pixel
== 1)
4166 color_table
= xpm_make_color_table_v (&put_color_table
,
4169 color_table
= xpm_make_color_table_h (&put_color_table
,
4172 while (num_colors
-- > 0)
4174 char *color
, *max_color
;
4175 int key
, next_key
, max_key
= 0;
4176 Lisp_Object symbol_color
= Qnil
, color_val
;
4179 expect (XPM_TK_STRING
);
4180 if (len
<= chars_per_pixel
|| len
>= BUFSIZ
+ chars_per_pixel
)
4182 memcpy (buffer
, beg
+ chars_per_pixel
, len
- chars_per_pixel
);
4183 buffer
[len
- chars_per_pixel
] = '\0';
4185 str
= strtok (buffer
, " \t");
4188 key
= xpm_str_to_color_key (str
);
4193 color
= strtok (NULL
, " \t");
4197 while ((str
= strtok (NULL
, " \t")) != NULL
)
4199 next_key
= xpm_str_to_color_key (str
);
4202 color
[strlen (color
)] = ' ';
4205 if (key
== XPM_COLOR_KEY_S
)
4207 if (NILP (symbol_color
))
4208 symbol_color
= build_string (color
);
4210 else if (max_key
< key
&& key
<= best_key
)
4220 if (!NILP (color_symbols
) && !NILP (symbol_color
))
4222 Lisp_Object specified_color
= Fassoc (symbol_color
, color_symbols
);
4224 if (CONSP (specified_color
) && STRINGP (XCDR (specified_color
)))
4226 if (xstrcasecmp (SSDATA (XCDR (specified_color
)), "None") == 0)
4228 else if (x_defined_color (f
, SSDATA (XCDR (specified_color
)),
4230 color_val
= make_number (cdef
.pixel
);
4233 if (NILP (color_val
) && max_key
> 0)
4235 if (xstrcasecmp (max_color
, "None") == 0)
4237 else if (x_defined_color (f
, max_color
, &cdef
, 0))
4238 color_val
= make_number (cdef
.pixel
);
4240 if (!NILP (color_val
))
4241 (*put_color_table
) (color_table
, beg
, chars_per_pixel
, color_val
);
4246 for (y
= 0; y
< height
; y
++)
4248 expect (XPM_TK_STRING
);
4250 if (len
< width
* chars_per_pixel
)
4252 for (x
= 0; x
< width
; x
++, str
+= chars_per_pixel
)
4254 Lisp_Object color_val
=
4255 (*get_color_table
) (color_table
, str
, chars_per_pixel
);
4257 XPutPixel (ximg
, x
, y
,
4258 (INTEGERP (color_val
) ? XINT (color_val
)
4259 : FRAME_FOREGROUND_PIXEL (f
)));
4261 XPutPixel (mask_img
, x
, y
,
4262 (!EQ (color_val
, Qt
) ? PIX_MASK_DRAW
4263 : (have_mask
= true, PIX_MASK_RETAIN
)));
4265 if (EQ (color_val
, Qt
))
4266 ns_set_alpha (ximg
, x
, y
, 0);
4274 img
->height
= height
;
4276 /* Maybe fill in the background field while we have ximg handy. */
4277 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
4278 IMAGE_BACKGROUND (img
, f
, ximg
);
4280 image_put_x_image (f
, img
, ximg
, 0);
4284 /* Fill in the background_transparent field while we have the
4286 image_background_transparent (img
, f
, mask_img
);
4288 image_put_x_image (f
, img
, mask_img
, 1);
4292 x_destroy_x_image (mask_img
);
4293 x_clear_image_1 (f
, img
, CLEAR_IMAGE_MASK
);
4299 image_error ("Invalid XPM file (%s)", img
->spec
);
4300 x_destroy_x_image (ximg
);
4301 x_destroy_x_image (mask_img
);
4302 x_clear_image (f
, img
);
4311 xpm_load (struct frame
*f
,
4315 Lisp_Object file_name
;
4317 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4318 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
4319 if (STRINGP (file_name
))
4322 Lisp_Object file
= x_find_image_fd (file_name
, &fd
);
4323 if (!STRINGP (file
))
4325 image_error ("Cannot find image file `%s'", file_name
);
4330 unsigned char *contents
= slurp_file (fd
, &size
);
4331 if (contents
== NULL
)
4333 image_error ("Error loading XPM image `%s'", file
);
4337 success_p
= xpm_load_image (f
, img
, contents
, contents
+ size
);
4344 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
4345 if (!STRINGP (data
))
4347 image_error ("Invalid image data `%s'", data
);
4350 success_p
= xpm_load_image (f
, img
, SDATA (data
),
4351 SDATA (data
) + SBYTES (data
));
4357 #endif /* HAVE_NS && !HAVE_XPM */
4361 /***********************************************************************
4363 ***********************************************************************/
4365 #ifdef COLOR_TABLE_SUPPORT
4367 /* An entry in the color table mapping an RGB color to a pixel color. */
4372 unsigned long pixel
;
4374 /* Next in color table collision list. */
4375 struct ct_color
*next
;
4378 /* The bucket vector size to use. Must be prime. */
4382 /* Value is a hash of the RGB color given by R, G, and B. */
4385 ct_hash_rgb (unsigned r
, unsigned g
, unsigned b
)
4387 return (r
<< 16) ^ (g
<< 8) ^ b
;
4390 /* The color hash table. */
4392 static struct ct_color
**ct_table
;
4394 /* Number of entries in the color table. */
4396 static int ct_colors_allocated
;
4399 ct_colors_allocated_max
=
4401 min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof (unsigned long))
4404 /* Initialize the color table. */
4407 init_color_table (void)
4409 int size
= CT_SIZE
* sizeof (*ct_table
);
4410 ct_table
= xzalloc (size
);
4411 ct_colors_allocated
= 0;
4415 /* Free memory associated with the color table. */
4418 free_color_table (void)
4421 struct ct_color
*p
, *next
;
4423 for (i
= 0; i
< CT_SIZE
; ++i
)
4424 for (p
= ct_table
[i
]; p
; p
= next
)
4435 /* Value is a pixel color for RGB color R, G, B on frame F. If an
4436 entry for that color already is in the color table, return the
4437 pixel color of that entry. Otherwise, allocate a new color for R,
4438 G, B, and make an entry in the color table. */
4440 static unsigned long
4441 lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
)
4443 unsigned hash
= ct_hash_rgb (r
, g
, b
);
4444 int i
= hash
% CT_SIZE
;
4446 Display_Info
*dpyinfo
;
4448 /* Handle TrueColor visuals specially, which improves performance by
4449 two orders of magnitude. Freeing colors on TrueColor visuals is
4450 a nop, and pixel colors specify RGB values directly. See also
4451 the Xlib spec, chapter 3.1. */
4452 dpyinfo
= FRAME_DISPLAY_INFO (f
);
4453 if (dpyinfo
->red_bits
> 0)
4455 /* Apply gamma-correction like normal color allocation does. */
4459 color
.red
= r
, color
.green
= g
, color
.blue
= b
;
4460 gamma_correct (f
, &color
);
4461 r
= color
.red
, g
= color
.green
, b
= color
.blue
;
4464 return x_make_truecolor_pixel (dpyinfo
, r
, g
, b
);
4467 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4468 if (p
->r
== r
&& p
->g
== g
&& p
->b
== b
)
4474 #ifdef HAVE_X_WINDOWS
4482 if (ct_colors_allocated_max
<= ct_colors_allocated
)
4483 return FRAME_FOREGROUND_PIXEL (f
);
4485 #ifdef HAVE_X_WINDOWS
4490 cmap
= FRAME_X_COLORMAP (f
);
4491 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4494 ++ct_colors_allocated
;
4495 p
= xmalloc (sizeof *p
);
4499 p
->pixel
= color
.pixel
;
4500 p
->next
= ct_table
[i
];
4504 return FRAME_FOREGROUND_PIXEL (f
);
4508 color
= PALETTERGB (r
, g
, b
);
4510 color
= RGB_TO_ULONG (r
, g
, b
);
4511 #endif /* HAVE_NTGUI */
4512 ++ct_colors_allocated
;
4513 p
= xmalloc (sizeof *p
);
4518 p
->next
= ct_table
[i
];
4520 #endif /* HAVE_X_WINDOWS */
4528 /* Look up pixel color PIXEL which is used on frame F in the color
4529 table. If not already present, allocate it. Value is PIXEL. */
4531 static unsigned long
4532 lookup_pixel_color (struct frame
*f
, unsigned long pixel
)
4534 int i
= pixel
% CT_SIZE
;
4537 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4538 if (p
->pixel
== pixel
)
4547 if (ct_colors_allocated
>= ct_colors_allocated_max
)
4548 return FRAME_FOREGROUND_PIXEL (f
);
4550 #ifdef HAVE_X_WINDOWS
4551 cmap
= FRAME_X_COLORMAP (f
);
4552 color
.pixel
= pixel
;
4553 x_query_color (f
, &color
);
4554 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4557 cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
4558 color
.pixel
= pixel
;
4559 XQueryColor (NULL
, cmap
, &color
);
4560 rc
= x_alloc_nearest_color (f
, cmap
, &color
);
4562 #endif /* HAVE_X_WINDOWS */
4566 ++ct_colors_allocated
;
4568 p
= xmalloc (sizeof *p
);
4573 p
->next
= ct_table
[i
];
4577 return FRAME_FOREGROUND_PIXEL (f
);
4583 /* Value is a vector of all pixel colors contained in the color table,
4584 allocated via xmalloc. Set *N to the number of colors. */
4586 static unsigned long *
4587 colors_in_color_table (int *n
)
4591 unsigned long *colors
;
4593 if (ct_colors_allocated
== 0)
4600 colors
= xmalloc (ct_colors_allocated
* sizeof *colors
);
4601 *n
= ct_colors_allocated
;
4603 for (i
= j
= 0; i
< CT_SIZE
; ++i
)
4604 for (p
= ct_table
[i
]; p
; p
= p
->next
)
4605 colors
[j
++] = p
->pixel
;
4611 #else /* COLOR_TABLE_SUPPORT */
4613 static unsigned long
4614 lookup_rgb_color (struct frame
*f
, int r
, int g
, int b
)
4617 return PALETTERGB (r
>> 8, g
>> 8, b
>> 8);
4618 #elif defined HAVE_NS
4619 return RGB_TO_ULONG (r
>> 8, g
>> 8, b
>> 8);
4621 xsignal1 (Qfile_error
,
4622 build_string ("This Emacs mishandles this image file type"));
4627 init_color_table (void)
4630 #endif /* COLOR_TABLE_SUPPORT */
4633 /***********************************************************************
4635 ***********************************************************************/
4637 /* Edge detection matrices for different edge-detection
4640 static int emboss_matrix
[9] = {
4642 2, -1, 0, /* y - 1 */
4644 0, 1, -2 /* y + 1 */
4647 static int laplace_matrix
[9] = {
4649 1, 0, 0, /* y - 1 */
4651 0, 0, -1 /* y + 1 */
4654 /* Value is the intensity of the color whose red/green/blue values
4657 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
4660 /* On frame F, return an array of XColor structures describing image
4661 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
4662 means also fill the red/green/blue members of the XColor
4663 structures. Value is a pointer to the array of XColors structures,
4664 allocated with xmalloc; it must be freed by the caller. */
4667 x_to_xcolors (struct frame
*f
, struct image
*img
, bool rgb_p
)
4671 XImagePtr_or_DC ximg
;
4675 #endif /* HAVE_NTGUI */
4677 if (INT_MULTIPLY_WRAPV (sizeof *colors
, img
->width
, &nbytes
)
4678 || INT_MULTIPLY_WRAPV (img
->height
, nbytes
, &nbytes
)
4679 || SIZE_MAX
< nbytes
)
4680 memory_full (SIZE_MAX
);
4681 colors
= xmalloc (nbytes
);
4683 /* Get the X image or create a memory device context for IMG. */
4684 ximg
= image_get_x_image_or_dc (f
, img
, 0, &prev
);
4686 /* Fill the `pixel' members of the XColor array. I wished there
4687 were an easy and portable way to circumvent XGetPixel. */
4689 for (y
= 0; y
< img
->height
; ++y
)
4691 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
4693 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4694 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4696 x_query_colors (f
, row
, img
->width
);
4700 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4702 /* W32_TODO: palette support needed here? */
4703 p
->pixel
= GET_PIXEL (ximg
, x
, y
);
4706 p
->red
= RED16_FROM_ULONG (p
->pixel
);
4707 p
->green
= GREEN16_FROM_ULONG (p
->pixel
);
4708 p
->blue
= BLUE16_FROM_ULONG (p
->pixel
);
4711 #endif /* HAVE_X_WINDOWS */
4714 image_unget_x_image_or_dc (img
, 0, ximg
, prev
);
4721 /* Put a pixel of COLOR at position X, Y in XIMG. XIMG must have been
4722 created with CreateDIBSection, with the pointer to the bit values
4723 stored in ximg->data. */
4726 XPutPixel (XImagePtr ximg
, int x
, int y
, COLORREF color
)
4728 int width
= ximg
->info
.bmiHeader
.biWidth
;
4729 unsigned char * pixel
;
4731 /* True color images. */
4732 if (ximg
->info
.bmiHeader
.biBitCount
== 24)
4734 int rowbytes
= width
* 3;
4735 /* Ensure scanlines are aligned on 4 byte boundaries. */
4737 rowbytes
+= 4 - (rowbytes
% 4);
4739 pixel
= ximg
->data
+ y
* rowbytes
+ x
* 3;
4740 /* Windows bitmaps are in BGR order. */
4741 *pixel
= GetBValue (color
);
4742 *(pixel
+ 1) = GetGValue (color
);
4743 *(pixel
+ 2) = GetRValue (color
);
4745 /* Monochrome images. */
4746 else if (ximg
->info
.bmiHeader
.biBitCount
== 1)
4748 int rowbytes
= width
/ 8;
4749 /* Ensure scanlines are aligned on 4 byte boundaries. */
4751 rowbytes
+= 4 - (rowbytes
% 4);
4752 pixel
= ximg
->data
+ y
* rowbytes
+ x
/ 8;
4753 /* Filter out palette info. */
4754 if (color
& 0x00ffffff)
4755 *pixel
= *pixel
| (1 << x
% 8);
4757 *pixel
= *pixel
& ~(1 << x
% 8);
4760 image_error ("XPutPixel: palette image not supported");
4763 #endif /* HAVE_NTGUI */
4765 /* Create IMG->pixmap from an array COLORS of XColor structures, whose
4766 RGB members are set. F is the frame on which this all happens.
4767 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
4770 x_from_xcolors (struct frame
*f
, struct image
*img
, XColor
*colors
)
4773 XImagePtr oimg
= NULL
;
4776 init_color_table ();
4778 x_clear_image_1 (f
, img
, CLEAR_IMAGE_PIXMAP
| CLEAR_IMAGE_COLORS
);
4779 image_create_x_image_and_pixmap (f
, img
, img
->width
, img
->height
, 0,
4782 for (y
= 0; y
< img
->height
; ++y
)
4783 for (x
= 0; x
< img
->width
; ++x
, ++p
)
4785 unsigned long pixel
;
4786 pixel
= lookup_rgb_color (f
, p
->red
, p
->green
, p
->blue
);
4787 XPutPixel (oimg
, x
, y
, pixel
);
4792 image_put_x_image (f
, img
, oimg
, 0);
4793 #ifdef COLOR_TABLE_SUPPORT
4794 img
->colors
= colors_in_color_table (&img
->ncolors
);
4795 free_color_table ();
4796 #endif /* COLOR_TABLE_SUPPORT */
4800 /* On frame F, perform edge-detection on image IMG.
4802 MATRIX is a nine-element array specifying the transformation
4803 matrix. See emboss_matrix for an example.
4805 COLOR_ADJUST is a color adjustment added to each pixel of the
4809 x_detect_edges (struct frame
*f
, struct image
*img
, int *matrix
, int color_adjust
)
4811 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4816 for (i
= sum
= 0; i
< 9; ++i
)
4817 sum
+= eabs (matrix
[i
]);
4819 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
4821 if (INT_MULTIPLY_WRAPV (sizeof *new, img
->width
, &nbytes
)
4822 || INT_MULTIPLY_WRAPV (img
->height
, nbytes
, &nbytes
))
4823 memory_full (SIZE_MAX
);
4824 new = xmalloc (nbytes
);
4826 for (y
= 0; y
< img
->height
; ++y
)
4828 p
= COLOR (new, 0, y
);
4829 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4830 p
= COLOR (new, img
->width
- 1, y
);
4831 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4834 for (x
= 1; x
< img
->width
- 1; ++x
)
4836 p
= COLOR (new, x
, 0);
4837 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4838 p
= COLOR (new, x
, img
->height
- 1);
4839 p
->red
= p
->green
= p
->blue
= 0xffff/2;
4842 for (y
= 1; y
< img
->height
- 1; ++y
)
4844 p
= COLOR (new, 1, y
);
4846 for (x
= 1; x
< img
->width
- 1; ++x
, ++p
)
4848 int r
, g
, b
, yy
, xx
;
4851 for (yy
= y
- 1; yy
< y
+ 2; ++yy
)
4852 for (xx
= x
- 1; xx
< x
+ 2; ++xx
, ++i
)
4855 XColor
*t
= COLOR (colors
, xx
, yy
);
4856 r
+= matrix
[i
] * t
->red
;
4857 g
+= matrix
[i
] * t
->green
;
4858 b
+= matrix
[i
] * t
->blue
;
4861 r
= (r
/ sum
+ color_adjust
) & 0xffff;
4862 g
= (g
/ sum
+ color_adjust
) & 0xffff;
4863 b
= (b
/ sum
+ color_adjust
) & 0xffff;
4864 p
->red
= p
->green
= p
->blue
= COLOR_INTENSITY (r
, g
, b
);
4869 x_from_xcolors (f
, img
, new);
4875 /* Perform the pre-defined `emboss' edge-detection on image IMG
4879 x_emboss (struct frame
*f
, struct image
*img
)
4881 x_detect_edges (f
, img
, emboss_matrix
, 0xffff / 2);
4885 /* Transform image IMG which is used on frame F with a Laplace
4886 edge-detection algorithm. The result is an image that can be used
4887 to draw disabled buttons, for example. */
4890 x_laplace (struct frame
*f
, struct image
*img
)
4892 x_detect_edges (f
, img
, laplace_matrix
, 45000);
4896 /* Perform edge-detection on image IMG on frame F, with specified
4897 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
4899 MATRIX must be either
4901 - a list of at least 9 numbers in row-major form
4902 - a vector of at least 9 numbers
4904 COLOR_ADJUST nil means use a default; otherwise it must be a
4908 x_edge_detection (struct frame
*f
, struct image
*img
, Lisp_Object matrix
,
4909 Lisp_Object color_adjust
)
4917 i
< 9 && CONSP (matrix
) && NUMBERP (XCAR (matrix
));
4918 ++i
, matrix
= XCDR (matrix
))
4919 trans
[i
] = XFLOATINT (XCAR (matrix
));
4921 else if (VECTORP (matrix
) && ASIZE (matrix
) >= 9)
4923 for (i
= 0; i
< 9 && NUMBERP (AREF (matrix
, i
)); ++i
)
4924 trans
[i
] = XFLOATINT (AREF (matrix
, i
));
4927 if (NILP (color_adjust
))
4928 color_adjust
= make_number (0xffff / 2);
4930 if (i
== 9 && NUMBERP (color_adjust
))
4931 x_detect_edges (f
, img
, trans
, XFLOATINT (color_adjust
));
4935 /* Transform image IMG on frame F so that it looks disabled. */
4938 x_disable_image (struct frame
*f
, struct image
*img
)
4940 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
4942 int n_planes
= dpyinfo
->n_planes
* dpyinfo
->n_cbits
;
4944 int n_planes
= dpyinfo
->n_planes
;
4945 #endif /* HAVE_NTGUI */
4949 /* Color (or grayscale). Convert to gray, and equalize. Just
4950 drawing such images with a stipple can look very odd, so
4951 we're using this method instead. */
4952 XColor
*colors
= x_to_xcolors (f
, img
, 1);
4954 const int h
= 15000;
4955 const int l
= 30000;
4957 for (p
= colors
, end
= colors
+ img
->width
* img
->height
;
4961 int i
= COLOR_INTENSITY (p
->red
, p
->green
, p
->blue
);
4962 int i2
= (0xffff - h
- l
) * i
/ 0xffff + l
;
4963 p
->red
= p
->green
= p
->blue
= i2
;
4966 x_from_xcolors (f
, img
, colors
);
4969 /* Draw a cross over the disabled image, if we must or if we
4971 if (n_planes
< 2 || cross_disabled_images
)
4974 #ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
4976 #define MaskForeground(f) WHITE_PIX_DEFAULT (f)
4978 Display
*dpy
= FRAME_X_DISPLAY (f
);
4981 image_sync_to_pixmaps (f
, img
);
4982 gc
= XCreateGC (dpy
, img
->pixmap
, 0, NULL
);
4983 XSetForeground (dpy
, gc
, BLACK_PIX_DEFAULT (f
));
4984 XDrawLine (dpy
, img
->pixmap
, gc
, 0, 0,
4985 img
->width
- 1, img
->height
- 1);
4986 XDrawLine (dpy
, img
->pixmap
, gc
, 0, img
->height
- 1,
4992 gc
= XCreateGC (dpy
, img
->mask
, 0, NULL
);
4993 XSetForeground (dpy
, gc
, MaskForeground (f
));
4994 XDrawLine (dpy
, img
->mask
, gc
, 0, 0,
4995 img
->width
- 1, img
->height
- 1);
4996 XDrawLine (dpy
, img
->mask
, gc
, 0, img
->height
- 1,
5000 #endif /* !HAVE_NS */
5005 hdc
= get_frame_dc (f
);
5006 bmpdc
= CreateCompatibleDC (hdc
);
5007 release_frame_dc (f
, hdc
);
5009 prev
= SelectObject (bmpdc
, img
->pixmap
);
5011 SetTextColor (bmpdc
, BLACK_PIX_DEFAULT (f
));
5012 MoveToEx (bmpdc
, 0, 0, NULL
);
5013 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
5014 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
5015 LineTo (bmpdc
, img
->width
- 1, 0);
5019 SelectObject (bmpdc
, img
->mask
);
5020 SetTextColor (bmpdc
, WHITE_PIX_DEFAULT (f
));
5021 MoveToEx (bmpdc
, 0, 0, NULL
);
5022 LineTo (bmpdc
, img
->width
- 1, img
->height
- 1);
5023 MoveToEx (bmpdc
, 0, img
->height
- 1, NULL
);
5024 LineTo (bmpdc
, img
->width
- 1, 0);
5026 SelectObject (bmpdc
, prev
);
5028 #endif /* HAVE_NTGUI */
5033 /* Build a mask for image IMG which is used on frame F. FILE is the
5034 name of an image file, for error messages. HOW determines how to
5035 determine the background color of IMG. If it is a list '(R G B)',
5036 with R, G, and B being integers >= 0, take that as the color of the
5037 background. Otherwise, determine the background color of IMG
5041 x_build_heuristic_mask (struct frame
*f
, struct image
*img
, Lisp_Object how
)
5043 XImagePtr_or_DC ximg
;
5050 #endif /* HAVE_NTGUI */
5052 bool use_img_background
;
5053 unsigned long bg
= 0;
5056 x_clear_image_1 (f
, img
, CLEAR_IMAGE_MASK
);
5060 /* Create an image and pixmap serving as mask. */
5061 if (! image_create_x_image_and_pixmap (f
, img
, img
->width
, img
->height
, 1,
5064 #endif /* !HAVE_NS */
5066 /* Create the bit array serving as mask. */
5067 row_width
= (img
->width
+ 7) / 8;
5068 mask_img
= xzalloc (row_width
* img
->height
);
5069 #endif /* HAVE_NTGUI */
5071 /* Get the X image or create a memory device context for IMG. */
5072 ximg
= image_get_x_image_or_dc (f
, img
, 0, &prev
);
5074 /* Determine the background color of ximg. If HOW is `(R G B)'
5075 take that as color. Otherwise, use the image's background color. */
5076 use_img_background
= 1;
5082 for (i
= 0; i
< 3 && CONSP (how
) && NATNUMP (XCAR (how
)); ++i
)
5084 rgb
[i
] = XFASTINT (XCAR (how
)) & 0xffff;
5088 if (i
== 3 && NILP (how
))
5090 char color_name
[30];
5091 sprintf (color_name
, "#%04x%04x%04x",
5092 rgb
[0] + 0u, rgb
[1] + 0u, rgb
[2] + 0u);
5095 0x00ffffff & /* Filter out palette info. */
5096 #endif /* HAVE_NTGUI */
5097 x_alloc_image_color (f
, img
, build_string (color_name
), 0));
5098 use_img_background
= 0;
5102 if (use_img_background
)
5103 bg
= four_corners_best (ximg
, img
->corners
, img
->width
, img
->height
);
5105 /* Set all bits in mask_img to 1 whose color in ximg is different
5106 from the background color bg. */
5108 for (y
= 0; y
< img
->height
; ++y
)
5109 for (x
= 0; x
< img
->width
; ++x
)
5111 XPutPixel (mask_img
, x
, y
, (XGetPixel (ximg
, x
, y
) != bg
5112 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
));
5114 if (XGetPixel (ximg
, x
, y
) == bg
)
5115 ns_set_alpha (ximg
, x
, y
, 0);
5116 #endif /* HAVE_NS */
5118 /* Fill in the background_transparent field while we have the mask handy. */
5119 image_background_transparent (img
, f
, mask_img
);
5121 /* Put mask_img into the image. */
5122 image_put_x_image (f
, img
, mask_img
, 1);
5123 #endif /* !HAVE_NS */
5125 for (y
= 0; y
< img
->height
; ++y
)
5126 for (x
= 0; x
< img
->width
; ++x
)
5128 COLORREF p
= GetPixel (ximg
, x
, y
);
5130 mask_img
[y
* row_width
+ x
/ 8] |= 1 << (x
% 8);
5133 /* Create the mask image. */
5134 img
->mask
= w32_create_pixmap_from_bitmap_data (img
->width
, img
->height
,
5136 /* Fill in the background_transparent field while we have the mask handy. */
5137 SelectObject (ximg
, img
->mask
);
5138 image_background_transparent (img
, f
, ximg
);
5140 /* Was: x_destroy_x_image ((XImagePtr )mask_img); which seems bogus ++kfs */
5142 #endif /* HAVE_NTGUI */
5144 image_unget_x_image_or_dc (img
, 0, ximg
, prev
);
5148 /***********************************************************************
5149 PBM (mono, gray, color)
5150 ***********************************************************************/
5152 static bool pbm_image_p (Lisp_Object object
);
5153 static bool pbm_load (struct frame
*f
, struct image
*img
);
5155 /* Indices of image specification fields in gs_format, below. */
5157 enum pbm_keyword_index
5173 /* Vector of image_keyword structures describing the format
5174 of valid user-defined image specifications. */
5176 static const struct image_keyword pbm_format
[PBM_LAST
] =
5178 {":type", IMAGE_SYMBOL_VALUE
, 1},
5179 {":file", IMAGE_STRING_VALUE
, 0},
5180 {":data", IMAGE_STRING_VALUE
, 0},
5181 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5182 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
5183 {":relief", IMAGE_INTEGER_VALUE
, 0},
5184 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5185 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5186 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5187 {":foreground", IMAGE_STRING_OR_NIL_VALUE
, 0},
5188 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
5191 /* Structure describing the image type `pbm'. */
5193 static struct image_type pbm_type
=
5195 SYMBOL_INDEX (Qpbm
),
5204 /* Return true if OBJECT is a valid PBM image specification. */
5207 pbm_image_p (Lisp_Object object
)
5209 struct image_keyword fmt
[PBM_LAST
];
5211 memcpy (fmt
, pbm_format
, sizeof fmt
);
5213 if (!parse_image_spec (object
, fmt
, PBM_LAST
, Qpbm
))
5216 /* Must specify either :data or :file. */
5217 return fmt
[PBM_DATA
].count
+ fmt
[PBM_FILE
].count
== 1;
5221 /* Get next char skipping comments in Netpbm header. Returns -1 at
5225 pbm_next_char (unsigned char **s
, unsigned char *end
)
5229 while (*s
< end
&& (c
= *(*s
)++, c
== '#'))
5231 /* Skip to the next line break. */
5232 while (*s
< end
&& (c
= *(*s
)++, c
!= '\n' && c
!= '\r'))
5242 /* Scan a decimal number from *S and return it. Advance *S while
5243 reading the number. END is the end of the string. Value is -1 at
5247 pbm_scan_number (unsigned char **s
, unsigned char *end
)
5249 int c
= 0, val
= -1;
5251 /* Skip white-space. */
5252 while ((c
= pbm_next_char (s
, end
)) != -1 && c_isspace (c
))
5257 /* Read decimal number. */
5259 while ((c
= pbm_next_char (s
, end
)) != -1 && c_isdigit (c
))
5260 val
= 10 * val
+ c
- '0';
5267 /* Load PBM image IMG for use on frame F. */
5270 pbm_load (struct frame
*f
, struct image
*img
)
5274 int width
, height
, max_color_idx
= 0;
5275 Lisp_Object specified_file
;
5276 enum {PBM_MONO
, PBM_GRAY
, PBM_COLOR
} type
;
5277 unsigned char *contents
= NULL
;
5278 unsigned char *end
, *p
;
5280 unsigned char *data
= 0;
5286 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5288 if (STRINGP (specified_file
))
5291 Lisp_Object file
= x_find_image_fd (specified_file
, &fd
);
5292 if (!STRINGP (file
))
5294 image_error ("Cannot find image file `%s'", specified_file
);
5299 contents
= slurp_file (fd
, &size
);
5300 if (contents
== NULL
)
5302 image_error ("Error reading `%s'", file
);
5307 end
= contents
+ size
;
5312 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5313 if (!STRINGP (data
))
5315 image_error ("Invalid image data `%s'", data
);
5319 end
= p
+ SBYTES (data
);
5322 /* Check magic number. */
5323 if (end
- p
< 2 || *p
++ != 'P')
5325 image_error ("Not a PBM image: `%s'", img
->spec
);
5328 img
->pixmap
= NO_PIXMAP
;
5335 raw_p
= 0, type
= PBM_MONO
;
5339 raw_p
= 0, type
= PBM_GRAY
;
5343 raw_p
= 0, type
= PBM_COLOR
;
5347 raw_p
= 1, type
= PBM_MONO
;
5351 raw_p
= 1, type
= PBM_GRAY
;
5355 raw_p
= 1, type
= PBM_COLOR
;
5359 image_error ("Not a PBM image: `%s'", img
->spec
);
5363 /* Read width, height, maximum color-component. Characters
5364 starting with `#' up to the end of a line are ignored. */
5365 width
= pbm_scan_number (&p
, end
);
5366 height
= pbm_scan_number (&p
, end
);
5369 data
= (unsigned char *) xmalloc (width
* height
* 4);
5370 dataptr
= (uint32_t *) data
;
5373 if (type
!= PBM_MONO
)
5375 max_color_idx
= pbm_scan_number (&p
, end
);
5376 if (max_color_idx
> 65535 || max_color_idx
< 0)
5378 image_error ("Unsupported maximum PBM color value");
5383 if (!check_image_size (f
, width
, height
))
5385 image_size_error ();
5390 if (!image_create_x_image_and_pixmap (f
, img
, width
, height
, 0, &ximg
, 0))
5394 /* Initialize the color hash table. */
5395 init_color_table ();
5397 if (type
== PBM_MONO
)
5400 struct image_keyword fmt
[PBM_LAST
];
5401 unsigned long fg
= FRAME_FOREGROUND_PIXEL (f
);
5402 unsigned long bg
= FRAME_BACKGROUND_PIXEL (f
);
5407 /* Parse the image specification. */
5408 memcpy (fmt
, pbm_format
, sizeof fmt
);
5409 parse_image_spec (img
->spec
, fmt
, PBM_LAST
, Qpbm
);
5411 /* Get foreground and background colors, maybe allocate colors. */
5413 if (! fmt
[PBM_FOREGROUND
].count
5414 || ! STRINGP (fmt
[PBM_FOREGROUND
].value
)
5415 || ! x_defined_color (f
, SSDATA (fmt
[PBM_FOREGROUND
].value
), &xfg
, 0))
5418 x_query_color (f
, &xfg
);
5420 fga32
= xcolor_to_argb32 (xfg
);
5422 if (! fmt
[PBM_BACKGROUND
].count
5423 || ! STRINGP (fmt
[PBM_BACKGROUND
].value
)
5424 || ! x_defined_color (f
, SSDATA (fmt
[PBM_BACKGROUND
].value
), &xbg
, 0))
5427 x_query_color (f
, &xbg
);
5429 bga32
= xcolor_to_argb32 (xbg
);
5431 if (fmt
[PBM_FOREGROUND
].count
5432 && STRINGP (fmt
[PBM_FOREGROUND
].value
))
5433 fg
= x_alloc_image_color (f
, img
, fmt
[PBM_FOREGROUND
].value
, fg
);
5434 if (fmt
[PBM_BACKGROUND
].count
5435 && STRINGP (fmt
[PBM_BACKGROUND
].value
))
5437 bg
= x_alloc_image_color (f
, img
, fmt
[PBM_BACKGROUND
].value
, bg
);
5438 img
->background
= bg
;
5439 img
->background_valid
= 1;
5443 for (y
= 0; y
< height
; ++y
)
5444 for (x
= 0; x
< width
; ++x
)
5455 x_destroy_x_image (ximg
);
5457 x_clear_image (f
, img
);
5458 image_error ("Invalid image size in image `%s'",
5468 g
= pbm_scan_number (&p
, end
);
5471 *dataptr
++ = g
? fga32
: bga32
;
5473 XPutPixel (ximg
, x
, y
, g
? fg
: bg
);
5479 int expected_size
= height
* width
;
5480 if (max_color_idx
> 255)
5482 if (type
== PBM_COLOR
)
5485 if (raw_p
&& p
+ expected_size
> end
)
5490 x_destroy_x_image (ximg
);
5492 x_clear_image (f
, img
);
5493 image_error ("Invalid image size in image `%s'", img
->spec
);
5497 for (y
= 0; y
< height
; ++y
)
5498 for (x
= 0; x
< width
; ++x
)
5502 if (type
== PBM_GRAY
&& raw_p
)
5505 if (max_color_idx
> 255)
5506 r
= g
= b
= r
* 256 + *p
++;
5508 else if (type
== PBM_GRAY
)
5509 r
= g
= b
= pbm_scan_number (&p
, end
);
5513 if (max_color_idx
> 255)
5516 if (max_color_idx
> 255)
5519 if (max_color_idx
> 255)
5524 r
= pbm_scan_number (&p
, end
);
5525 g
= pbm_scan_number (&p
, end
);
5526 b
= pbm_scan_number (&p
, end
);
5529 if (r
< 0 || g
< 0 || b
< 0)
5534 x_destroy_x_image (ximg
);
5536 image_error ("Invalid pixel value in image `%s'", img
->spec
);
5541 r
= (double) r
* 255 / max_color_idx
;
5542 g
= (double) g
* 255 / max_color_idx
;
5543 b
= (double) b
* 255 / max_color_idx
;
5544 *dataptr
++ = (0xff << 24) | (r
<< 16) | (g
<< 8) | b
;
5546 /* RGB values are now in the range 0..max_color_idx.
5547 Scale this to the range 0..0xffff supported by X. */
5548 r
= (double) r
* 65535 / max_color_idx
;
5549 g
= (double) g
* 65535 / max_color_idx
;
5550 b
= (double) b
* 65535 / max_color_idx
;
5551 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
5556 #ifdef COLOR_TABLE_SUPPORT
5557 /* Store in IMG->colors the colors allocated for the image, and
5558 free the color table. */
5559 img
->colors
= colors_in_color_table (&img
->ncolors
);
5560 free_color_table ();
5561 #endif /* COLOR_TABLE_SUPPORT */
5564 img
->height
= height
;
5566 /* Maybe fill in the background field while we have ximg handy. */
5569 create_cairo_image_surface (img
, data
, width
, height
);
5571 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
5572 /* Casting avoids a GCC warning. */
5573 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
5575 /* Put ximg into the image. */
5576 image_put_x_image (f
, img
, ximg
, 0);
5579 /* X and W32 versions did it here, MAC version above. ++kfs
5581 img->height = height; */
5588 /***********************************************************************
5590 ***********************************************************************/
5592 #if defined (HAVE_PNG) || defined (HAVE_NS) || defined (USE_CAIRO)
5594 /* Function prototypes. */
5596 static bool png_image_p (Lisp_Object object
);
5597 static bool png_load (struct frame
*f
, struct image
*img
);
5599 /* Indices of image specification fields in png_format, below. */
5601 enum png_keyword_index
5616 /* Vector of image_keyword structures describing the format
5617 of valid user-defined image specifications. */
5619 static const struct image_keyword png_format
[PNG_LAST
] =
5621 {":type", IMAGE_SYMBOL_VALUE
, 1},
5622 {":data", IMAGE_STRING_VALUE
, 0},
5623 {":file", IMAGE_STRING_VALUE
, 0},
5624 {":ascent", IMAGE_ASCENT_VALUE
, 0},
5625 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
5626 {":relief", IMAGE_INTEGER_VALUE
, 0},
5627 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5628 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5629 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
5630 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
5633 #if defined HAVE_NTGUI && defined WINDOWSNT
5634 static bool init_png_functions (void);
5636 #define init_png_functions NULL
5639 /* Structure describing the image type `png'. */
5641 static struct image_type png_type
=
5643 SYMBOL_INDEX (Qpng
),
5651 /* Return true if OBJECT is a valid PNG image specification. */
5654 png_image_p (Lisp_Object object
)
5656 struct image_keyword fmt
[PNG_LAST
];
5657 memcpy (fmt
, png_format
, sizeof fmt
);
5659 if (!parse_image_spec (object
, fmt
, PNG_LAST
, Qpng
))
5662 /* Must specify either the :data or :file keyword. */
5663 return fmt
[PNG_FILE
].count
+ fmt
[PNG_DATA
].count
== 1;
5666 #endif /* HAVE_PNG || HAVE_NS || USE_CAIRO */
5669 #if (defined HAVE_PNG && !defined HAVE_NS) || defined USE_CAIRO
5672 /* PNG library details. */
5674 DEF_DLL_FN (png_voidp
, png_get_io_ptr
, (png_structp
));
5675 DEF_DLL_FN (int, png_sig_cmp
, (png_bytep
, png_size_t
, png_size_t
));
5676 DEF_DLL_FN (png_structp
, png_create_read_struct
,
5677 (png_const_charp
, png_voidp
, png_error_ptr
, png_error_ptr
));
5678 DEF_DLL_FN (png_infop
, png_create_info_struct
, (png_structp
));
5679 DEF_DLL_FN (void, png_destroy_read_struct
,
5680 (png_structpp
, png_infopp
, png_infopp
));
5681 DEF_DLL_FN (void, png_set_read_fn
, (png_structp
, png_voidp
, png_rw_ptr
));
5682 DEF_DLL_FN (void, png_set_sig_bytes
, (png_structp
, int));
5683 DEF_DLL_FN (void, png_read_info
, (png_structp
, png_infop
));
5684 DEF_DLL_FN (png_uint_32
, png_get_IHDR
,
5685 (png_structp
, png_infop
, png_uint_32
*, png_uint_32
*,
5686 int *, int *, int *, int *, int *));
5687 DEF_DLL_FN (png_uint_32
, png_get_valid
, (png_structp
, png_infop
, png_uint_32
));
5688 DEF_DLL_FN (void, png_set_strip_16
, (png_structp
));
5689 DEF_DLL_FN (void, png_set_expand
, (png_structp
));
5690 DEF_DLL_FN (void, png_set_gray_to_rgb
, (png_structp
));
5691 DEF_DLL_FN (void, png_set_background
,
5692 (png_structp
, png_color_16p
, int, int, double));
5693 DEF_DLL_FN (png_uint_32
, png_get_bKGD
,
5694 (png_structp
, png_infop
, png_color_16p
*));
5695 DEF_DLL_FN (void, png_read_update_info
, (png_structp
, png_infop
));
5696 DEF_DLL_FN (png_byte
, png_get_channels
, (png_structp
, png_infop
));
5697 DEF_DLL_FN (png_size_t
, png_get_rowbytes
, (png_structp
, png_infop
));
5698 DEF_DLL_FN (void, png_read_image
, (png_structp
, png_bytepp
));
5699 DEF_DLL_FN (void, png_read_end
, (png_structp
, png_infop
));
5700 DEF_DLL_FN (void, png_error
, (png_structp
, png_const_charp
));
5702 # if (PNG_LIBPNG_VER >= 10500)
5703 DEF_DLL_FN (void, png_longjmp
, (png_structp
, int)) PNG_NORETURN
;
5704 DEF_DLL_FN (jmp_buf *, png_set_longjmp_fn
,
5705 (png_structp
, png_longjmp_ptr
, size_t));
5706 # endif /* libpng version >= 1.5 */
5709 init_png_functions (void)
5713 if (!(library
= w32_delayed_load (Qpng
)))
5716 LOAD_DLL_FN (library
, png_get_io_ptr
);
5717 LOAD_DLL_FN (library
, png_sig_cmp
);
5718 LOAD_DLL_FN (library
, png_create_read_struct
);
5719 LOAD_DLL_FN (library
, png_create_info_struct
);
5720 LOAD_DLL_FN (library
, png_destroy_read_struct
);
5721 LOAD_DLL_FN (library
, png_set_read_fn
);
5722 LOAD_DLL_FN (library
, png_set_sig_bytes
);
5723 LOAD_DLL_FN (library
, png_read_info
);
5724 LOAD_DLL_FN (library
, png_get_IHDR
);
5725 LOAD_DLL_FN (library
, png_get_valid
);
5726 LOAD_DLL_FN (library
, png_set_strip_16
);
5727 LOAD_DLL_FN (library
, png_set_expand
);
5728 LOAD_DLL_FN (library
, png_set_gray_to_rgb
);
5729 LOAD_DLL_FN (library
, png_set_background
);
5730 LOAD_DLL_FN (library
, png_get_bKGD
);
5731 LOAD_DLL_FN (library
, png_read_update_info
);
5732 LOAD_DLL_FN (library
, png_get_channels
);
5733 LOAD_DLL_FN (library
, png_get_rowbytes
);
5734 LOAD_DLL_FN (library
, png_read_image
);
5735 LOAD_DLL_FN (library
, png_read_end
);
5736 LOAD_DLL_FN (library
, png_error
);
5738 # if (PNG_LIBPNG_VER >= 10500)
5739 LOAD_DLL_FN (library
, png_longjmp
);
5740 LOAD_DLL_FN (library
, png_set_longjmp_fn
);
5741 # endif /* libpng version >= 1.5 */
5746 # undef png_create_info_struct
5747 # undef png_create_read_struct
5748 # undef png_destroy_read_struct
5750 # undef png_get_bKGD
5751 # undef png_get_channels
5752 # undef png_get_IHDR
5753 # undef png_get_io_ptr
5754 # undef png_get_rowbytes
5755 # undef png_get_valid
5757 # undef png_read_end
5758 # undef png_read_image
5759 # undef png_read_info
5760 # undef png_read_update_info
5761 # undef png_set_background
5762 # undef png_set_expand
5763 # undef png_set_gray_to_rgb
5764 # undef png_set_longjmp_fn
5765 # undef png_set_read_fn
5766 # undef png_set_sig_bytes
5767 # undef png_set_strip_16
5770 # define png_create_info_struct fn_png_create_info_struct
5771 # define png_create_read_struct fn_png_create_read_struct
5772 # define png_destroy_read_struct fn_png_destroy_read_struct
5773 # define png_error fn_png_error
5774 # define png_get_bKGD fn_png_get_bKGD
5775 # define png_get_channels fn_png_get_channels
5776 # define png_get_IHDR fn_png_get_IHDR
5777 # define png_get_io_ptr fn_png_get_io_ptr
5778 # define png_get_rowbytes fn_png_get_rowbytes
5779 # define png_get_valid fn_png_get_valid
5780 # define png_longjmp fn_png_longjmp
5781 # define png_read_end fn_png_read_end
5782 # define png_read_image fn_png_read_image
5783 # define png_read_info fn_png_read_info
5784 # define png_read_update_info fn_png_read_update_info
5785 # define png_set_background fn_png_set_background
5786 # define png_set_expand fn_png_set_expand
5787 # define png_set_gray_to_rgb fn_png_set_gray_to_rgb
5788 # define png_set_longjmp_fn fn_png_set_longjmp_fn
5789 # define png_set_read_fn fn_png_set_read_fn
5790 # define png_set_sig_bytes fn_png_set_sig_bytes
5791 # define png_set_strip_16 fn_png_set_strip_16
5792 # define png_sig_cmp fn_png_sig_cmp
5794 # endif /* WINDOWSNT */
5796 /* Fast implementations of setjmp and longjmp. Although setjmp and longjmp
5797 will do, POSIX _setjmp and _longjmp (if available) are often faster.
5798 Do not use sys_setjmp, as PNG supports only jmp_buf.
5799 It's OK if the longjmp substitute restores the signal mask. */
5800 # ifdef HAVE__SETJMP
5801 # define FAST_SETJMP(j) _setjmp (j)
5802 # define FAST_LONGJMP _longjmp
5804 # define FAST_SETJMP(j) setjmp (j)
5805 # define FAST_LONGJMP longjmp
5808 # if PNG_LIBPNG_VER < 10500
5809 # define PNG_LONGJMP(ptr) FAST_LONGJMP ((ptr)->jmpbuf, 1)
5810 # define PNG_JMPBUF(ptr) ((ptr)->jmpbuf)
5812 /* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908) */
5813 # define PNG_LONGJMP(ptr) png_longjmp (ptr, 1)
5814 # define PNG_JMPBUF(ptr) \
5815 (*png_set_longjmp_fn (ptr, FAST_LONGJMP, sizeof (jmp_buf)))
5818 /* Error and warning handlers installed when the PNG library
5821 static _Noreturn
void
5822 my_png_error (png_struct
*png_ptr
, const char *msg
)
5824 eassert (png_ptr
!= NULL
);
5825 /* Avoid compiler warning about deprecated direct access to
5826 png_ptr's fields in libpng versions 1.4.x. */
5827 image_error ("PNG error: %s", build_string (msg
));
5828 PNG_LONGJMP (png_ptr
);
5833 my_png_warning (png_struct
*png_ptr
, const char *msg
)
5835 eassert (png_ptr
!= NULL
);
5836 image_error ("PNG warning: %s", build_string (msg
));
5839 /* Memory source for PNG decoding. */
5841 struct png_memory_storage
5843 unsigned char *bytes
; /* The data */
5844 ptrdiff_t len
; /* How big is it? */
5845 ptrdiff_t index
; /* Where are we? */
5849 /* Function set as reader function when reading PNG image from memory.
5850 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5851 bytes from the input to DATA. */
5854 png_read_from_memory (png_structp png_ptr
, png_bytep data
, png_size_t length
)
5856 struct png_memory_storage
*tbr
= png_get_io_ptr (png_ptr
);
5858 if (length
> tbr
->len
- tbr
->index
)
5859 png_error (png_ptr
, "Read error");
5861 memcpy (data
, tbr
->bytes
+ tbr
->index
, length
);
5862 tbr
->index
= tbr
->index
+ length
;
5866 /* Function set as reader function when reading PNG image from a file.
5867 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5868 bytes from the input to DATA. */
5871 png_read_from_file (png_structp png_ptr
, png_bytep data
, png_size_t length
)
5873 FILE *fp
= png_get_io_ptr (png_ptr
);
5875 if (fread (data
, 1, length
, fp
) < length
)
5876 png_error (png_ptr
, "Read error");
5880 /* Load PNG image IMG for use on frame F. Value is true if
5883 struct png_load_context
5885 /* These are members so that longjmp doesn't munge local variables. */
5886 png_struct
*png_ptr
;
5895 png_load_body (struct frame
*f
, struct image
*img
, struct png_load_context
*c
)
5897 Lisp_Object specified_file
;
5898 Lisp_Object specified_data
;
5901 png_struct
*png_ptr
;
5902 png_info
*info_ptr
= NULL
, *end_info
= NULL
;
5905 png_byte
*pixels
= NULL
;
5906 png_byte
**rows
= NULL
;
5907 png_uint_32 width
, height
;
5908 int bit_depth
, color_type
, interlace_type
;
5910 png_uint_32 row_bytes
;
5912 struct png_memory_storage tbr
; /* Data to be read */
5916 unsigned char *data
= 0;
5919 XImagePtr ximg
, mask_img
= NULL
;
5922 /* Find out what file to load. */
5923 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
5924 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
5925 IF_LINT (Lisp_Object
volatile specified_data_volatile
= specified_data
);
5927 if (NILP (specified_data
))
5930 Lisp_Object file
= x_find_image_fd (specified_file
, &fd
);
5931 if (!STRINGP (file
))
5933 image_error ("Cannot find image file `%s'", specified_file
);
5937 /* Open the image file. */
5938 fp
= fdopen (fd
, "rb");
5941 image_error ("Cannot open image file `%s'", file
);
5945 /* Check PNG signature. */
5946 if (fread (sig
, 1, sizeof sig
, fp
) != sizeof sig
5947 || png_sig_cmp (sig
, 0, sizeof sig
))
5950 image_error ("Not a PNG file: `%s'", file
);
5956 if (!STRINGP (specified_data
))
5958 image_error ("Invalid image data `%s'", specified_data
);
5962 /* Read from memory. */
5963 tbr
.bytes
= SDATA (specified_data
);
5964 tbr
.len
= SBYTES (specified_data
);
5967 /* Check PNG signature. */
5968 if (tbr
.len
< sizeof sig
5969 || png_sig_cmp (tbr
.bytes
, 0, sizeof sig
))
5971 image_error ("Not a PNG image: `%s'", img
->spec
);
5975 /* Need to skip past the signature. */
5976 tbr
.bytes
+= sizeof (sig
);
5979 /* Initialize read and info structs for PNG lib. */
5980 png_ptr
= png_create_read_struct (PNG_LIBPNG_VER_STRING
,
5985 info_ptr
= png_create_info_struct (png_ptr
);
5986 end_info
= png_create_info_struct (png_ptr
);
5989 c
->png_ptr
= png_ptr
;
5990 c
->info_ptr
= info_ptr
;
5991 c
->end_info
= end_info
;
5996 if (! (info_ptr
&& end_info
))
5998 png_destroy_read_struct (&c
->png_ptr
, &c
->info_ptr
, &c
->end_info
);
6003 if (fp
) fclose (fp
);
6007 /* Set error jump-back. We come back here when the PNG library
6008 detects an error. */
6009 if (FAST_SETJMP (PNG_JMPBUF (png_ptr
)))
6013 png_destroy_read_struct (&c
->png_ptr
, &c
->info_ptr
, &c
->end_info
);
6021 /* Silence a bogus diagnostic; see GCC bug 54561. */
6022 IF_LINT (fp
= c
->fp
);
6023 IF_LINT (specified_data
= specified_data_volatile
);
6025 /* Read image info. */
6026 if (!NILP (specified_data
))
6027 png_set_read_fn (png_ptr
, &tbr
, png_read_from_memory
);
6029 png_set_read_fn (png_ptr
, fp
, png_read_from_file
);
6031 png_set_sig_bytes (png_ptr
, sizeof sig
);
6032 png_read_info (png_ptr
, info_ptr
);
6033 png_get_IHDR (png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
,
6034 &interlace_type
, NULL
, NULL
);
6036 if (! (width
<= INT_MAX
&& height
<= INT_MAX
6037 && check_image_size (f
, width
, height
)))
6039 image_size_error ();
6044 /* Create the X image and pixmap now, so that the work below can be
6045 omitted if the image is too large for X. */
6046 if (!image_create_x_image_and_pixmap (f
, img
, width
, height
, 0, &ximg
, 0))
6050 /* If image contains simply transparency data, we prefer to
6051 construct a clipping mask. */
6052 if (png_get_valid (png_ptr
, info_ptr
, PNG_INFO_tRNS
))
6057 /* This function is easier to write if we only have to handle
6058 one data format: RGB or RGBA with 8 bits per channel. Let's
6059 transform other formats into that format. */
6061 /* Strip more than 8 bits per channel. */
6062 if (bit_depth
== 16)
6063 png_set_strip_16 (png_ptr
);
6065 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
6067 png_set_expand (png_ptr
);
6069 /* Convert grayscale images to RGB. */
6070 if (color_type
== PNG_COLOR_TYPE_GRAY
6071 || color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
6072 png_set_gray_to_rgb (png_ptr
);
6074 /* Handle alpha channel by combining the image with a background
6075 color. Do this only if a real alpha channel is supplied. For
6076 simple transparency, we prefer a clipping mask. */
6079 /* png_color_16 *image_bg; */
6080 Lisp_Object specified_bg
6081 = image_spec_value (img
->spec
, QCbackground
, NULL
);
6084 /* If the user specified a color, try to use it; if not, use the
6085 current frame background, ignoring any default background
6086 color set by the image. */
6087 if (STRINGP (specified_bg
)
6088 ? x_defined_color (f
, SSDATA (specified_bg
), &color
, false)
6089 : (x_query_frame_background_color (f
, &color
), true))
6090 /* The user specified `:background', use that. */
6092 int shift
= bit_depth
== 16 ? 0 : 8;
6093 png_color_16 bg
= { 0 };
6094 bg
.red
= color
.red
>> shift
;
6095 bg
.green
= color
.green
>> shift
;
6096 bg
.blue
= color
.blue
>> shift
;
6098 png_set_background (png_ptr
, &bg
,
6099 PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
6103 /* Update info structure. */
6104 png_read_update_info (png_ptr
, info_ptr
);
6106 /* Get number of channels. Valid values are 1 for grayscale images
6107 and images with a palette, 2 for grayscale images with transparency
6108 information (alpha channel), 3 for RGB images, and 4 for RGB
6109 images with alpha channel, i.e. RGBA. If conversions above were
6110 sufficient we should only have 3 or 4 channels here. */
6111 channels
= png_get_channels (png_ptr
, info_ptr
);
6112 eassert (channels
== 3 || channels
== 4);
6114 /* Number of bytes needed for one row of the image. */
6115 row_bytes
= png_get_rowbytes (png_ptr
, info_ptr
);
6117 /* Allocate memory for the image. */
6118 if (INT_MULTIPLY_WRAPV (row_bytes
, sizeof *pixels
, &nbytes
)
6119 || INT_MULTIPLY_WRAPV (nbytes
, height
, &nbytes
))
6120 memory_full (SIZE_MAX
);
6121 c
->pixels
= pixels
= xmalloc (nbytes
);
6122 c
->rows
= rows
= xmalloc (height
* sizeof *rows
);
6123 for (i
= 0; i
< height
; ++i
)
6124 rows
[i
] = pixels
+ i
* row_bytes
;
6126 /* Read the entire image. */
6127 png_read_image (png_ptr
, rows
);
6128 png_read_end (png_ptr
, info_ptr
);
6136 data
= (unsigned char *) xmalloc (width
* height
* 4);
6137 dataptr
= (uint32_t *) data
;
6139 /* Create an image and pixmap serving as mask if the PNG image
6140 contains an alpha channel. */
6143 && !image_create_x_image_and_pixmap (f
, img
, width
, height
, 1,
6146 x_destroy_x_image (ximg
);
6147 x_clear_image_1 (f
, img
, CLEAR_IMAGE_PIXMAP
);
6152 /* Fill the X image and mask from PNG data. */
6153 init_color_table ();
6155 for (y
= 0; y
< height
; ++y
)
6157 png_byte
*p
= rows
[y
];
6159 for (x
= 0; x
< width
; ++x
)
6168 if (channels
== 4) a
= *p
++;
6169 *dataptr
++ = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
6174 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, r
, g
, b
));
6175 /* An alpha channel, aka mask channel, associates variable
6176 transparency with an image. Where other image formats
6177 support binary transparency---fully transparent or fully
6178 opaque---PNG allows up to 254 levels of partial transparency.
6179 The PNG library implements partial transparency by combining
6180 the image with a specified background color.
6182 I'm not sure how to handle this here nicely: because the
6183 background on which the image is displayed may change, for
6184 real alpha channel support, it would be necessary to create
6185 a new image for each possible background.
6187 What I'm doing now is that a mask is created if we have
6188 boolean transparency information. Otherwise I'm using
6189 the frame's background color to combine the image with. */
6194 XPutPixel (mask_img
, x
, y
, *p
> 0 ? PIX_MASK_DRAW
: PIX_MASK_RETAIN
);
6201 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6202 /* Set IMG's background color from the PNG image, unless the user
6206 if (png_get_bKGD (png_ptr
, info_ptr
, &bg
))
6208 img
->background
= lookup_rgb_color (f
, bg
->red
, bg
->green
, bg
->blue
);
6209 img
->background_valid
= 1;
6213 # ifdef COLOR_TABLE_SUPPORT
6214 /* Remember colors allocated for this image. */
6215 img
->colors
= colors_in_color_table (&img
->ncolors
);
6216 free_color_table ();
6217 # endif /* COLOR_TABLE_SUPPORT */
6220 png_destroy_read_struct (&c
->png_ptr
, &c
->info_ptr
, &c
->end_info
);
6225 img
->height
= height
;
6228 create_cairo_image_surface (img
, data
, width
, height
);
6230 /* Maybe fill in the background field while we have ximg handy.
6231 Casting avoids a GCC warning. */
6232 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6234 /* Put ximg into the image. */
6235 image_put_x_image (f
, img
, ximg
, 0);
6237 /* Same for the mask. */
6240 /* Fill in the background_transparent field while we have the
6241 mask handy. Casting avoids a GCC warning. */
6242 image_background_transparent (img
, f
, (XImagePtr_or_DC
)mask_img
);
6244 image_put_x_image (f
, img
, mask_img
, 1);
6252 png_load (struct frame
*f
, struct image
*img
)
6254 struct png_load_context c
;
6255 return png_load_body (f
, img
, &c
);
6258 #elif defined HAVE_NS
6261 png_load (struct frame
*f
, struct image
*img
)
6263 return ns_load_image (f
, img
,
6264 image_spec_value (img
->spec
, QCfile
, NULL
),
6265 image_spec_value (img
->spec
, QCdata
, NULL
));
6269 #endif /* HAVE_NS */
6273 /***********************************************************************
6275 ***********************************************************************/
6277 #if defined (HAVE_JPEG) || defined (HAVE_NS)
6279 static bool jpeg_image_p (Lisp_Object object
);
6280 static bool jpeg_load (struct frame
*f
, struct image
*img
);
6282 /* Indices of image specification fields in gs_format, below. */
6284 enum jpeg_keyword_index
6293 JPEG_HEURISTIC_MASK
,
6299 /* Vector of image_keyword structures describing the format
6300 of valid user-defined image specifications. */
6302 static const struct image_keyword jpeg_format
[JPEG_LAST
] =
6304 {":type", IMAGE_SYMBOL_VALUE
, 1},
6305 {":data", IMAGE_STRING_VALUE
, 0},
6306 {":file", IMAGE_STRING_VALUE
, 0},
6307 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6308 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
6309 {":relief", IMAGE_INTEGER_VALUE
, 0},
6310 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6311 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6312 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6313 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
6316 #if defined HAVE_NTGUI && defined WINDOWSNT
6317 static bool init_jpeg_functions (void);
6319 #define init_jpeg_functions NULL
6322 /* Structure describing the image type `jpeg'. */
6324 static struct image_type jpeg_type
=
6326 SYMBOL_INDEX (Qjpeg
),
6330 init_jpeg_functions
,
6334 /* Return true if OBJECT is a valid JPEG image specification. */
6337 jpeg_image_p (Lisp_Object object
)
6339 struct image_keyword fmt
[JPEG_LAST
];
6341 memcpy (fmt
, jpeg_format
, sizeof fmt
);
6343 if (!parse_image_spec (object
, fmt
, JPEG_LAST
, Qjpeg
))
6346 /* Must specify either the :data or :file keyword. */
6347 return fmt
[JPEG_FILE
].count
+ fmt
[JPEG_DATA
].count
== 1;
6350 #endif /* HAVE_JPEG || HAVE_NS */
6354 /* Work around a warning about HAVE_STDLIB_H being redefined in
6356 # ifdef HAVE_STDLIB_H
6357 # undef HAVE_STDLIB_H
6360 # if defined (HAVE_NTGUI) && !defined (__WIN32__)
6361 /* In older releases of the jpeg library, jpeglib.h will define boolean
6362 differently depending on __WIN32__, so make sure it is defined. */
6363 # define __WIN32__ 1
6366 /* rpcndr.h (via windows.h) and jpeglib.h both define boolean types.
6367 Some versions of jpeglib try to detect whether rpcndr.h is loaded,
6368 using the Windows boolean type instead of the jpeglib boolean type
6369 if so. Cygwin jpeglib, however, doesn't try to detect whether its
6370 headers are included along with windows.h, so under Cygwin, jpeglib
6371 attempts to define a conflicting boolean type. Worse, forcing
6372 Cygwin jpeglib headers to use the Windows boolean type doesn't work
6373 because it created an ABI incompatibility between the
6374 already-compiled jpeg library and the header interface definition.
6376 The best we can do is to define jpeglib's boolean type to a
6377 different name. This name, jpeg_boolean, remains in effect through
6378 the rest of image.c.
6380 # if defined CYGWIN && defined HAVE_NTGUI
6381 # define boolean jpeg_boolean
6383 # include <jpeglib.h>
6384 # include <jerror.h>
6388 /* JPEG library details. */
6389 DEF_DLL_FN (void, jpeg_CreateDecompress
, (j_decompress_ptr
, int, size_t));
6390 DEF_DLL_FN (boolean
, jpeg_start_decompress
, (j_decompress_ptr
));
6391 DEF_DLL_FN (boolean
, jpeg_finish_decompress
, (j_decompress_ptr
));
6392 DEF_DLL_FN (void, jpeg_destroy_decompress
, (j_decompress_ptr
));
6393 DEF_DLL_FN (int, jpeg_read_header
, (j_decompress_ptr
, boolean
));
6394 DEF_DLL_FN (JDIMENSION
, jpeg_read_scanlines
,
6395 (j_decompress_ptr
, JSAMPARRAY
, JDIMENSION
));
6396 DEF_DLL_FN (struct jpeg_error_mgr
*, jpeg_std_error
,
6397 (struct jpeg_error_mgr
*));
6398 DEF_DLL_FN (boolean
, jpeg_resync_to_restart
, (j_decompress_ptr
, int));
6401 init_jpeg_functions (void)
6405 if (!(library
= w32_delayed_load (Qjpeg
)))
6408 LOAD_DLL_FN (library
, jpeg_finish_decompress
);
6409 LOAD_DLL_FN (library
, jpeg_read_scanlines
);
6410 LOAD_DLL_FN (library
, jpeg_start_decompress
);
6411 LOAD_DLL_FN (library
, jpeg_read_header
);
6412 LOAD_DLL_FN (library
, jpeg_CreateDecompress
);
6413 LOAD_DLL_FN (library
, jpeg_destroy_decompress
);
6414 LOAD_DLL_FN (library
, jpeg_std_error
);
6415 LOAD_DLL_FN (library
, jpeg_resync_to_restart
);
6419 # undef jpeg_CreateDecompress
6420 # undef jpeg_destroy_decompress
6421 # undef jpeg_finish_decompress
6422 # undef jpeg_read_header
6423 # undef jpeg_read_scanlines
6424 # undef jpeg_resync_to_restart
6425 # undef jpeg_start_decompress
6426 # undef jpeg_std_error
6428 # define jpeg_CreateDecompress fn_jpeg_CreateDecompress
6429 # define jpeg_destroy_decompress fn_jpeg_destroy_decompress
6430 # define jpeg_finish_decompress fn_jpeg_finish_decompress
6431 # define jpeg_read_header fn_jpeg_read_header
6432 # define jpeg_read_scanlines fn_jpeg_read_scanlines
6433 # define jpeg_resync_to_restart fn_jpeg_resync_to_restart
6434 # define jpeg_start_decompress fn_jpeg_start_decompress
6435 # define jpeg_std_error fn_jpeg_std_error
6437 /* Wrapper since we can't directly assign the function pointer
6438 to another function pointer that was declared more completely easily. */
6440 jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo
, int desired
)
6442 return jpeg_resync_to_restart (cinfo
, desired
);
6444 # undef jpeg_resync_to_restart
6445 # define jpeg_resync_to_restart jpeg_resync_to_restart_wrapper
6447 # endif /* WINDOWSNT */
6449 struct my_jpeg_error_mgr
6451 struct jpeg_error_mgr pub
;
6452 sys_jmp_buf setjmp_buffer
;
6454 /* The remaining members are so that longjmp doesn't munge local
6456 struct jpeg_decompress_struct cinfo
;
6460 MY_JPEG_INVALID_IMAGE_SIZE
,
6461 MY_JPEG_CANNOT_CREATE_X
6466 static _Noreturn
void
6467 my_error_exit (j_common_ptr cinfo
)
6469 struct my_jpeg_error_mgr
*mgr
= (struct my_jpeg_error_mgr
*) cinfo
->err
;
6470 mgr
->failure_code
= MY_JPEG_ERROR_EXIT
;
6471 sys_longjmp (mgr
->setjmp_buffer
, 1);
6475 /* Init source method for JPEG data source manager. Called by
6476 jpeg_read_header() before any data is actually read. See
6477 libjpeg.doc from the JPEG lib distribution. */
6480 our_common_init_source (j_decompress_ptr cinfo
)
6485 /* Method to terminate data source. Called by
6486 jpeg_finish_decompress() after all data has been processed. */
6489 our_common_term_source (j_decompress_ptr cinfo
)
6494 /* Fill input buffer method for JPEG data source manager. Called
6495 whenever more data is needed. We read the whole image in one step,
6496 so this only adds a fake end of input marker at the end. */
6498 static JOCTET our_memory_buffer
[2];
6501 our_memory_fill_input_buffer (j_decompress_ptr cinfo
)
6503 /* Insert a fake EOI marker. */
6504 struct jpeg_source_mgr
*src
= cinfo
->src
;
6506 our_memory_buffer
[0] = (JOCTET
) 0xFF;
6507 our_memory_buffer
[1] = (JOCTET
) JPEG_EOI
;
6509 src
->next_input_byte
= our_memory_buffer
;
6510 src
->bytes_in_buffer
= 2;
6515 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6516 is the JPEG data source manager. */
6519 our_memory_skip_input_data (j_decompress_ptr cinfo
, long int num_bytes
)
6521 struct jpeg_source_mgr
*src
= cinfo
->src
;
6525 if (num_bytes
> src
->bytes_in_buffer
)
6526 ERREXIT (cinfo
, JERR_INPUT_EOF
);
6528 src
->bytes_in_buffer
-= num_bytes
;
6529 src
->next_input_byte
+= num_bytes
;
6534 /* Set up the JPEG lib for reading an image from DATA which contains
6535 LEN bytes. CINFO is the decompression info structure created for
6536 reading the image. */
6539 jpeg_memory_src (j_decompress_ptr cinfo
, JOCTET
*data
, ptrdiff_t len
)
6541 struct jpeg_source_mgr
*src
= cinfo
->src
;
6545 /* First time for this JPEG object? */
6546 src
= cinfo
->mem
->alloc_small ((j_common_ptr
) cinfo
,
6547 JPOOL_PERMANENT
, sizeof *src
);
6549 src
->next_input_byte
= data
;
6552 src
->init_source
= our_common_init_source
;
6553 src
->fill_input_buffer
= our_memory_fill_input_buffer
;
6554 src
->skip_input_data
= our_memory_skip_input_data
;
6555 src
->resync_to_restart
= jpeg_resync_to_restart
; /* Use default method. */
6556 src
->term_source
= our_common_term_source
;
6557 src
->bytes_in_buffer
= len
;
6558 src
->next_input_byte
= data
;
6562 struct jpeg_stdio_mgr
6564 struct jpeg_source_mgr mgr
;
6571 /* Size of buffer to read JPEG from file.
6572 Not too big, as we want to use alloc_small. */
6573 #define JPEG_STDIO_BUFFER_SIZE 8192
6576 /* Fill input buffer method for JPEG data source manager. Called
6577 whenever more data is needed. The data is read from a FILE *. */
6580 our_stdio_fill_input_buffer (j_decompress_ptr cinfo
)
6582 struct jpeg_stdio_mgr
*src
;
6584 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6589 bytes
= fread (src
->buffer
, 1, JPEG_STDIO_BUFFER_SIZE
, src
->file
);
6591 src
->mgr
.bytes_in_buffer
= bytes
;
6594 WARNMS (cinfo
, JWRN_JPEG_EOF
);
6596 src
->buffer
[0] = (JOCTET
) 0xFF;
6597 src
->buffer
[1] = (JOCTET
) JPEG_EOI
;
6598 src
->mgr
.bytes_in_buffer
= 2;
6600 src
->mgr
.next_input_byte
= src
->buffer
;
6607 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
6608 is the JPEG data source manager. */
6611 our_stdio_skip_input_data (j_decompress_ptr cinfo
, long int num_bytes
)
6613 struct jpeg_stdio_mgr
*src
;
6614 src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6616 while (num_bytes
> 0 && !src
->finished
)
6618 if (num_bytes
<= src
->mgr
.bytes_in_buffer
)
6620 src
->mgr
.bytes_in_buffer
-= num_bytes
;
6621 src
->mgr
.next_input_byte
+= num_bytes
;
6626 num_bytes
-= src
->mgr
.bytes_in_buffer
;
6627 src
->mgr
.bytes_in_buffer
= 0;
6628 src
->mgr
.next_input_byte
= NULL
;
6630 our_stdio_fill_input_buffer (cinfo
);
6636 /* Set up the JPEG lib for reading an image from a FILE *.
6637 CINFO is the decompression info structure created for
6638 reading the image. */
6641 jpeg_file_src (j_decompress_ptr cinfo
, FILE *fp
)
6643 struct jpeg_stdio_mgr
*src
= (struct jpeg_stdio_mgr
*) cinfo
->src
;
6647 /* First time for this JPEG object? */
6648 src
= cinfo
->mem
->alloc_small ((j_common_ptr
) cinfo
,
6649 JPOOL_PERMANENT
, sizeof *src
);
6650 cinfo
->src
= (struct jpeg_source_mgr
*) src
;
6651 src
->buffer
= cinfo
->mem
->alloc_small ((j_common_ptr
) cinfo
,
6653 JPEG_STDIO_BUFFER_SIZE
);
6658 src
->mgr
.init_source
= our_common_init_source
;
6659 src
->mgr
.fill_input_buffer
= our_stdio_fill_input_buffer
;
6660 src
->mgr
.skip_input_data
= our_stdio_skip_input_data
;
6661 src
->mgr
.resync_to_restart
= jpeg_resync_to_restart
; /* Use default. */
6662 src
->mgr
.term_source
= our_common_term_source
;
6663 src
->mgr
.bytes_in_buffer
= 0;
6664 src
->mgr
.next_input_byte
= NULL
;
6667 /* Load image IMG for use on frame F. Patterned after example.c
6668 from the JPEG lib. */
6671 jpeg_load_body (struct frame
*f
, struct image
*img
,
6672 struct my_jpeg_error_mgr
*mgr
)
6674 Lisp_Object specified_file
;
6675 Lisp_Object specified_data
;
6676 /* The 'volatile' silences a bogus diagnostic; see GCC bug 54561. */
6677 FILE * IF_LINT (volatile) fp
= NULL
;
6679 int row_stride
, x
, y
;
6680 unsigned long *colors
;
6684 XImagePtr ximg
= NULL
;
6687 /* Open the JPEG file. */
6688 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
6689 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
6690 IF_LINT (Lisp_Object
volatile specified_data_volatile
= specified_data
);
6692 if (NILP (specified_data
))
6695 Lisp_Object file
= x_find_image_fd (specified_file
, &fd
);
6696 if (!STRINGP (file
))
6698 image_error ("Cannot find image file `%s'", specified_file
);
6702 fp
= fdopen (fd
, "rb");
6705 image_error ("Cannot open `%s'", file
);
6709 else if (!STRINGP (specified_data
))
6711 image_error ("Invalid image data `%s'", specified_data
);
6715 /* Customize libjpeg's error handling to call my_error_exit when an
6716 error is detected. This function will perform a longjmp. */
6717 mgr
->cinfo
.err
= jpeg_std_error (&mgr
->pub
);
6718 mgr
->pub
.error_exit
= my_error_exit
;
6719 if (sys_setjmp (mgr
->setjmp_buffer
))
6721 switch (mgr
->failure_code
)
6723 case MY_JPEG_ERROR_EXIT
:
6725 char buf
[JMSG_LENGTH_MAX
];
6726 mgr
->cinfo
.err
->format_message ((j_common_ptr
) &mgr
->cinfo
, buf
);
6727 image_error ("Error reading JPEG image `%s': %s",
6728 img
->spec
, build_string (buf
));
6732 case MY_JPEG_INVALID_IMAGE_SIZE
:
6733 image_size_error ();
6736 case MY_JPEG_CANNOT_CREATE_X
:
6740 /* Close the input file and destroy the JPEG object. */
6743 jpeg_destroy_decompress (&mgr
->cinfo
);
6745 /* If we already have an XImage, free that. */
6747 x_destroy_x_image (ximg
);
6749 /* Free pixmap and colors. */
6750 x_clear_image (f
, img
);
6754 /* Silence a bogus diagnostic; see GCC bug 54561. */
6755 IF_LINT (specified_data
= specified_data_volatile
);
6757 /* Create the JPEG decompression object. Let it read from fp.
6758 Read the JPEG image header. */
6759 jpeg_CreateDecompress (&mgr
->cinfo
, JPEG_LIB_VERSION
, sizeof *&mgr
->cinfo
);
6761 if (NILP (specified_data
))
6762 jpeg_file_src (&mgr
->cinfo
, fp
);
6764 jpeg_memory_src (&mgr
->cinfo
, SDATA (specified_data
),
6765 SBYTES (specified_data
));
6767 jpeg_read_header (&mgr
->cinfo
, 1);
6769 /* Customize decompression so that color quantization will be used.
6770 Start decompression. */
6771 mgr
->cinfo
.quantize_colors
= 1;
6772 jpeg_start_decompress (&mgr
->cinfo
);
6773 width
= img
->width
= mgr
->cinfo
.output_width
;
6774 height
= img
->height
= mgr
->cinfo
.output_height
;
6776 if (!check_image_size (f
, width
, height
))
6778 mgr
->failure_code
= MY_JPEG_INVALID_IMAGE_SIZE
;
6779 sys_longjmp (mgr
->setjmp_buffer
, 1);
6783 /* Create X image and pixmap. */
6784 if (!image_create_x_image_and_pixmap (f
, img
, width
, height
, 0, &ximg
, 0))
6786 mgr
->failure_code
= MY_JPEG_CANNOT_CREATE_X
;
6787 sys_longjmp (mgr
->setjmp_buffer
, 1);
6791 /* Allocate colors. When color quantization is used,
6792 mgr->cinfo.actual_number_of_colors has been set with the number of
6793 colors generated, and mgr->cinfo.colormap is a two-dimensional array
6794 of color indices in the range 0..mgr->cinfo.actual_number_of_colors.
6795 No more than 255 colors will be generated. */
6798 if (mgr
->cinfo
.out_color_components
> 2)
6799 ir
= 0, ig
= 1, ib
= 2;
6800 else if (mgr
->cinfo
.out_color_components
> 1)
6801 ir
= 0, ig
= 1, ib
= 0;
6803 ir
= 0, ig
= 0, ib
= 0;
6806 /* Use the color table mechanism because it handles colors that
6807 cannot be allocated nicely. Such colors will be replaced with
6808 a default color, and we don't have to care about which colors
6809 can be freed safely, and which can't. */
6810 init_color_table ();
6811 SAFE_NALLOCA (colors
, 1, mgr
->cinfo
.actual_number_of_colors
);
6813 for (i
= 0; i
< mgr
->cinfo
.actual_number_of_colors
; ++i
)
6815 /* Multiply RGB values with 255 because X expects RGB values
6816 in the range 0..0xffff. */
6817 int r
= mgr
->cinfo
.colormap
[ir
][i
] << 8;
6818 int g
= mgr
->cinfo
.colormap
[ig
][i
] << 8;
6819 int b
= mgr
->cinfo
.colormap
[ib
][i
] << 8;
6820 colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
6824 #ifdef COLOR_TABLE_SUPPORT
6825 /* Remember those colors actually allocated. */
6826 img
->colors
= colors_in_color_table (&img
->ncolors
);
6827 free_color_table ();
6828 #endif /* COLOR_TABLE_SUPPORT */
6832 row_stride
= width
* mgr
->cinfo
.output_components
;
6833 buffer
= mgr
->cinfo
.mem
->alloc_sarray ((j_common_ptr
) &mgr
->cinfo
,
6834 JPOOL_IMAGE
, row_stride
, 1);
6837 unsigned char *data
= (unsigned char *) xmalloc (width
*height
*4);
6838 uint32_t *dataptr
= (uint32_t *) data
;
6841 for (y
= 0; y
< height
; ++y
)
6843 jpeg_read_scanlines (&mgr
->cinfo
, buffer
, 1);
6845 for (x
= 0; x
< width
; ++x
)
6848 r
= mgr
->cinfo
.colormap
[ir
][i
];
6849 g
= mgr
->cinfo
.colormap
[ig
][i
];
6850 b
= mgr
->cinfo
.colormap
[ib
][i
];
6851 *dataptr
++ = (0xff << 24) | (r
<< 16) | (g
<< 8) | b
;
6855 create_cairo_image_surface (img
, data
, width
, height
);
6858 for (y
= 0; y
< height
; ++y
)
6860 jpeg_read_scanlines (&mgr
->cinfo
, buffer
, 1);
6861 for (x
= 0; x
< mgr
->cinfo
.output_width
; ++x
)
6862 XPutPixel (ximg
, x
, y
, colors
[buffer
[0][x
]]);
6867 jpeg_finish_decompress (&mgr
->cinfo
);
6868 jpeg_destroy_decompress (&mgr
->cinfo
);
6873 /* Maybe fill in the background field while we have ximg handy. */
6874 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
6875 /* Casting avoids a GCC warning. */
6876 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
6878 /* Put ximg into the image. */
6879 image_put_x_image (f
, img
, ximg
, 0);
6886 jpeg_load (struct frame
*f
, struct image
*img
)
6888 struct my_jpeg_error_mgr mgr
;
6889 return jpeg_load_body (f
, img
, &mgr
);
6892 #else /* HAVE_JPEG */
6896 jpeg_load (struct frame
*f
, struct image
*img
)
6898 return ns_load_image (f
, img
,
6899 image_spec_value (img
->spec
, QCfile
, NULL
),
6900 image_spec_value (img
->spec
, QCdata
, NULL
));
6902 #endif /* HAVE_NS */
6904 #endif /* !HAVE_JPEG */
6908 /***********************************************************************
6910 ***********************************************************************/
6912 #if defined (HAVE_TIFF) || defined (HAVE_NS)
6914 static bool tiff_image_p (Lisp_Object object
);
6915 static bool tiff_load (struct frame
*f
, struct image
*img
);
6917 /* Indices of image specification fields in tiff_format, below. */
6919 enum tiff_keyword_index
6928 TIFF_HEURISTIC_MASK
,
6935 /* Vector of image_keyword structures describing the format
6936 of valid user-defined image specifications. */
6938 static const struct image_keyword tiff_format
[TIFF_LAST
] =
6940 {":type", IMAGE_SYMBOL_VALUE
, 1},
6941 {":data", IMAGE_STRING_VALUE
, 0},
6942 {":file", IMAGE_STRING_VALUE
, 0},
6943 {":ascent", IMAGE_ASCENT_VALUE
, 0},
6944 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
6945 {":relief", IMAGE_INTEGER_VALUE
, 0},
6946 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6947 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6948 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
6949 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
6950 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0}
6953 #if defined HAVE_NTGUI && defined WINDOWSNT
6954 static bool init_tiff_functions (void);
6956 #define init_tiff_functions NULL
6959 /* Structure describing the image type `tiff'. */
6961 static struct image_type tiff_type
=
6963 SYMBOL_INDEX (Qtiff
),
6967 init_tiff_functions
,
6971 /* Return true if OBJECT is a valid TIFF image specification. */
6974 tiff_image_p (Lisp_Object object
)
6976 struct image_keyword fmt
[TIFF_LAST
];
6977 memcpy (fmt
, tiff_format
, sizeof fmt
);
6979 if (!parse_image_spec (object
, fmt
, TIFF_LAST
, Qtiff
))
6982 /* Must specify either the :data or :file keyword. */
6983 return fmt
[TIFF_FILE
].count
+ fmt
[TIFF_DATA
].count
== 1;
6986 #endif /* HAVE_TIFF || HAVE_NS */
6990 # include <tiffio.h>
6994 /* TIFF library details. */
6995 DEF_DLL_FN (TIFFErrorHandler
, TIFFSetErrorHandler
, (TIFFErrorHandler
));
6996 DEF_DLL_FN (TIFFErrorHandler
, TIFFSetWarningHandler
, (TIFFErrorHandler
));
6997 DEF_DLL_FN (TIFF
*, TIFFOpen
, (const char *, const char *));
6998 DEF_DLL_FN (TIFF
*, TIFFClientOpen
,
6999 (const char *, const char *, thandle_t
, TIFFReadWriteProc
,
7000 TIFFReadWriteProc
, TIFFSeekProc
, TIFFCloseProc
, TIFFSizeProc
,
7001 TIFFMapFileProc
, TIFFUnmapFileProc
));
7002 DEF_DLL_FN (int, TIFFGetField
, (TIFF
*, ttag_t
, ...));
7003 DEF_DLL_FN (int, TIFFReadRGBAImage
, (TIFF
*, uint32
, uint32
, uint32
*, int));
7004 DEF_DLL_FN (void, TIFFClose
, (TIFF
*));
7005 DEF_DLL_FN (int, TIFFSetDirectory
, (TIFF
*, tdir_t
));
7008 init_tiff_functions (void)
7012 if (!(library
= w32_delayed_load (Qtiff
)))
7015 LOAD_DLL_FN (library
, TIFFSetErrorHandler
);
7016 LOAD_DLL_FN (library
, TIFFSetWarningHandler
);
7017 LOAD_DLL_FN (library
, TIFFOpen
);
7018 LOAD_DLL_FN (library
, TIFFClientOpen
);
7019 LOAD_DLL_FN (library
, TIFFGetField
);
7020 LOAD_DLL_FN (library
, TIFFReadRGBAImage
);
7021 LOAD_DLL_FN (library
, TIFFClose
);
7022 LOAD_DLL_FN (library
, TIFFSetDirectory
);
7026 # undef TIFFClientOpen
7028 # undef TIFFGetField
7030 # undef TIFFReadRGBAImage
7031 # undef TIFFSetDirectory
7032 # undef TIFFSetErrorHandler
7033 # undef TIFFSetWarningHandler
7035 # define TIFFClientOpen fn_TIFFClientOpen
7036 # define TIFFClose fn_TIFFClose
7037 # define TIFFGetField fn_TIFFGetField
7038 # define TIFFOpen fn_TIFFOpen
7039 # define TIFFReadRGBAImage fn_TIFFReadRGBAImage
7040 # define TIFFSetDirectory fn_TIFFSetDirectory
7041 # define TIFFSetErrorHandler fn_TIFFSetErrorHandler
7042 # define TIFFSetWarningHandler fn_TIFFSetWarningHandler
7044 # endif /* WINDOWSNT */
7047 /* Reading from a memory buffer for TIFF images Based on the PNG
7048 memory source, but we have to provide a lot of extra functions.
7051 We really only need to implement read and seek, but I am not
7052 convinced that the TIFF library is smart enough not to destroy
7053 itself if we only hand it the function pointers we need to
7058 unsigned char *bytes
;
7065 tiff_read_from_memory (thandle_t data
, tdata_t buf
, tsize_t size
)
7067 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
7069 size
= min (size
, src
->len
- src
->index
);
7070 memcpy (buf
, src
->bytes
+ src
->index
, size
);
7076 tiff_write_from_memory (thandle_t data
, tdata_t buf
, tsize_t size
)
7082 tiff_seek_in_memory (thandle_t data
, toff_t off
, int whence
)
7084 tiff_memory_source
*src
= (tiff_memory_source
*) data
;
7089 case SEEK_SET
: /* Go from beginning of source. */
7093 case SEEK_END
: /* Go from end of source. */
7094 idx
= src
->len
+ off
;
7097 case SEEK_CUR
: /* Go from current position. */
7098 idx
= src
->index
+ off
;
7101 default: /* Invalid `whence'. */
7105 if (idx
> src
->len
|| idx
< 0)
7113 tiff_close_memory (thandle_t data
)
7120 tiff_mmap_memory (thandle_t data
, tdata_t
*pbase
, toff_t
*psize
)
7122 /* It is already _IN_ memory. */
7127 tiff_unmap_memory (thandle_t data
, tdata_t base
, toff_t size
)
7129 /* We don't need to do this. */
7133 tiff_size_of_memory (thandle_t data
)
7135 return ((tiff_memory_source
*) data
)->len
;
7138 /* GCC 3.x on x86 Windows targets has a bug that triggers an internal
7139 compiler error compiling tiff_handler, see Bugzilla bug #17406
7140 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17406). Declaring
7141 this function as external works around that problem. */
7142 # if defined (__MINGW32__) && __GNUC__ == 3
7143 # define MINGW_STATIC
7145 # define MINGW_STATIC static
7149 tiff_handler (const char *, const char *, const char *, va_list)
7150 ATTRIBUTE_FORMAT_PRINTF (3, 0);
7152 tiff_handler (const char *log_format
, const char *title
,
7153 const char *format
, va_list ap
)
7155 /* doprnt is not suitable here, as TIFF handlers are called from
7156 libtiff and are passed arbitrary printf directives. Instead, use
7157 vsnprintf, taking care to be portable to nonstandard environments
7158 where vsnprintf returns -1 on buffer overflow. Since it's just a
7159 log entry, it's OK to truncate it. */
7161 int len
= vsnprintf (buf
, sizeof buf
, format
, ap
);
7162 add_to_log (log_format
, build_string (title
),
7163 make_string (buf
, max (0, min (len
, sizeof buf
- 1))));
7165 # undef MINGW_STATIC
7167 static void tiff_error_handler (const char *, const char *, va_list)
7168 ATTRIBUTE_FORMAT_PRINTF (2, 0);
7170 tiff_error_handler (const char *title
, const char *format
, va_list ap
)
7172 tiff_handler ("TIFF error: %s %s", title
, format
, ap
);
7176 static void tiff_warning_handler (const char *, const char *, va_list)
7177 ATTRIBUTE_FORMAT_PRINTF (2, 0);
7179 tiff_warning_handler (const char *title
, const char *format
, va_list ap
)
7181 tiff_handler ("TIFF warning: %s %s", title
, format
, ap
);
7185 /* Load TIFF image IMG for use on frame F. Value is true if
7189 tiff_load (struct frame
*f
, struct image
*img
)
7191 Lisp_Object specified_file
;
7192 Lisp_Object specified_data
;
7194 int width
, height
, x
, y
, count
;
7198 tiff_memory_source memsrc
;
7201 specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7202 specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7204 TIFFSetErrorHandler ((TIFFErrorHandler
) tiff_error_handler
);
7205 TIFFSetWarningHandler ((TIFFErrorHandler
) tiff_warning_handler
);
7207 if (NILP (specified_data
))
7209 /* Read from a file */
7210 Lisp_Object file
= x_find_image_file (specified_file
);
7211 if (!STRINGP (file
))
7213 image_error ("Cannot find image file `%s'", specified_file
);
7217 Lisp_Object encoded_file
= ENCODE_FILE (file
);
7219 encoded_file
= ansi_encode_filename (encoded_file
);
7222 /* Try to open the image file. */
7223 tiff
= TIFFOpen (SSDATA (encoded_file
), "r");
7226 image_error ("Cannot open `%s'", file
);
7232 if (!STRINGP (specified_data
))
7234 image_error ("Invalid image data `%s'", specified_data
);
7238 /* Memory source! */
7239 memsrc
.bytes
= SDATA (specified_data
);
7240 memsrc
.len
= SBYTES (specified_data
);
7243 tiff
= TIFFClientOpen ("memory_source", "r", (thandle_t
)&memsrc
,
7244 tiff_read_from_memory
,
7245 tiff_write_from_memory
,
7246 tiff_seek_in_memory
,
7248 tiff_size_of_memory
,
7254 image_error ("Cannot open memory source for `%s'", img
->spec
);
7259 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
7260 if (INTEGERP (image
))
7262 EMACS_INT ino
= XFASTINT (image
);
7263 if (! (TYPE_MINIMUM (tdir_t
) <= ino
&& ino
<= TYPE_MAXIMUM (tdir_t
)
7264 && TIFFSetDirectory (tiff
, ino
)))
7266 image_error ("Invalid image number `%s' in image `%s'",
7273 /* Get width and height of the image, and allocate a raster buffer
7274 of width x height 32-bit values. */
7275 TIFFGetField (tiff
, TIFFTAG_IMAGEWIDTH
, &width
);
7276 TIFFGetField (tiff
, TIFFTAG_IMAGELENGTH
, &height
);
7278 if (!check_image_size (f
, width
, height
))
7280 image_size_error ();
7285 /* Create the X image and pixmap. */
7286 if (! (height
<= min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof *buf
/ width
7287 && image_create_x_image_and_pixmap (f
, img
, width
, height
, 0,
7294 buf
= xmalloc (sizeof *buf
* width
* height
);
7296 rc
= TIFFReadRGBAImage (tiff
, width
, height
, buf
, 0);
7298 /* Count the number of images in the file. */
7299 for (count
= 1; TIFFSetDirectory (tiff
, count
); count
++)
7303 img
->lisp_data
= Fcons (Qcount
,
7304 Fcons (make_number (count
),
7310 image_error ("Error reading TIFF image `%s'", img
->spec
);
7317 unsigned char *data
= (unsigned char *) xmalloc (width
*height
*4);
7318 uint32_t *dataptr
= (uint32_t *) data
;
7320 for (y
= 0; y
< height
; ++y
)
7322 uint32
*row
= buf
+ (height
- 1 - y
) * width
;
7323 for (x
= 0; x
< width
; ++x
)
7325 uint32 abgr
= row
[x
];
7326 int r
= TIFFGetR (abgr
);
7327 int g
= TIFFGetG (abgr
);
7328 int b
= TIFFGetB (abgr
);
7329 int a
= TIFFGetA (abgr
);
7330 *dataptr
++ = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
7334 create_cairo_image_surface (img
, data
, width
, height
);
7337 /* Initialize the color table. */
7338 init_color_table ();
7340 /* Process the pixel raster. Origin is in the lower-left corner. */
7341 for (y
= 0; y
< height
; ++y
)
7343 uint32
*row
= buf
+ y
* width
;
7345 for (x
= 0; x
< width
; ++x
)
7347 uint32 abgr
= row
[x
];
7348 int r
= TIFFGetR (abgr
) << 8;
7349 int g
= TIFFGetG (abgr
) << 8;
7350 int b
= TIFFGetB (abgr
) << 8;
7351 XPutPixel (ximg
, x
, height
- 1 - y
, lookup_rgb_color (f
, r
, g
, b
));
7355 # ifdef COLOR_TABLE_SUPPORT
7356 /* Remember the colors allocated for the image. Free the color table. */
7357 img
->colors
= colors_in_color_table (&img
->ncolors
);
7358 free_color_table ();
7359 # endif /* COLOR_TABLE_SUPPORT */
7362 img
->height
= height
;
7364 /* Maybe fill in the background field while we have ximg handy. */
7365 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
7366 /* Casting avoids a GCC warning on W32. */
7367 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
7369 /* Put ximg into the image. */
7370 image_put_x_image (f
, img
, ximg
, 0);
7372 #endif /* ! USE_CAIRO */
7378 #elif defined HAVE_NS
7381 tiff_load (struct frame
*f
, struct image
*img
)
7383 return ns_load_image (f
, img
,
7384 image_spec_value (img
->spec
, QCfile
, NULL
),
7385 image_spec_value (img
->spec
, QCdata
, NULL
));
7392 /***********************************************************************
7394 ***********************************************************************/
7396 #if defined (HAVE_GIF) || defined (HAVE_NS)
7398 static bool gif_image_p (Lisp_Object object
);
7399 static bool gif_load (struct frame
*f
, struct image
*img
);
7400 static void gif_clear_image (struct frame
*f
, struct image
*img
);
7402 /* Indices of image specification fields in gif_format, below. */
7404 enum gif_keyword_index
7420 /* Vector of image_keyword structures describing the format
7421 of valid user-defined image specifications. */
7423 static const struct image_keyword gif_format
[GIF_LAST
] =
7425 {":type", IMAGE_SYMBOL_VALUE
, 1},
7426 {":data", IMAGE_STRING_VALUE
, 0},
7427 {":file", IMAGE_STRING_VALUE
, 0},
7428 {":ascent", IMAGE_ASCENT_VALUE
, 0},
7429 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
7430 {":relief", IMAGE_INTEGER_VALUE
, 0},
7431 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7432 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7433 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
7434 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE
, 0},
7435 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
7438 #if defined HAVE_NTGUI && defined WINDOWSNT
7439 static bool init_gif_functions (void);
7441 #define init_gif_functions NULL
7444 /* Structure describing the image type `gif'. */
7446 static struct image_type gif_type
=
7448 SYMBOL_INDEX (Qgif
),
7456 /* Free X resources of GIF image IMG which is used on frame F. */
7459 gif_clear_image (struct frame
*f
, struct image
*img
)
7461 img
->lisp_data
= Qnil
;
7462 x_clear_image (f
, img
);
7465 /* Return true if OBJECT is a valid GIF image specification. */
7468 gif_image_p (Lisp_Object object
)
7470 struct image_keyword fmt
[GIF_LAST
];
7471 memcpy (fmt
, gif_format
, sizeof fmt
);
7473 if (!parse_image_spec (object
, fmt
, GIF_LAST
, Qgif
))
7476 /* Must specify either the :data or :file keyword. */
7477 return fmt
[GIF_FILE
].count
+ fmt
[GIF_DATA
].count
== 1;
7480 #endif /* HAVE_GIF */
7486 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
7487 Undefine before redefining to avoid a preprocessor warning. */
7491 /* avoid conflict with QuickdrawText.h */
7492 # define DrawText gif_DrawText
7493 # include <gif_lib.h>
7496 /* Giflib before 5.0 didn't define these macros (used only if HAVE_NTGUI). */
7497 # ifndef GIFLIB_MINOR
7498 # define GIFLIB_MINOR 0
7500 # ifndef GIFLIB_RELEASE
7501 # define GIFLIB_RELEASE 0
7504 # else /* HAVE_NTGUI */
7506 # include <gif_lib.h>
7508 # endif /* HAVE_NTGUI */
7510 /* Giflib before 5.0 didn't define these macros. */
7511 # ifndef GIFLIB_MAJOR
7512 # define GIFLIB_MAJOR 4
7515 /* GifErrorString is declared to return char const * when GIFLIB_MAJOR
7516 and GIFLIB_MINOR indicate 5.1 or later. Do not bother using it in
7517 earlier releases, where either it returns char * or GIFLIB_MINOR
7518 may be incorrect. */
7519 # define HAVE_GIFERRORSTRING (5 < GIFLIB_MAJOR + (1 <= GIFLIB_MINOR))
7523 /* GIF library details. */
7524 # if GIFLIB_MAJOR + (GIFLIB_MINOR >= 1) > 5
7525 DEF_DLL_FN (int, DGifCloseFile
, (GifFileType
*, int *));
7527 DEF_DLL_FN (int, DGifCloseFile
, (GifFileType
*));
7529 DEF_DLL_FN (int, DGifSlurp
, (GifFileType
*));
7530 # if GIFLIB_MAJOR < 5
7531 DEF_DLL_FN (GifFileType
*, DGifOpen
, (void *, InputFunc
));
7532 DEF_DLL_FN (GifFileType
*, DGifOpenFileName
, (const char *));
7534 DEF_DLL_FN (GifFileType
*, DGifOpen
, (void *, InputFunc
, int *));
7535 DEF_DLL_FN (GifFileType
*, DGifOpenFileName
, (const char *, int *));
7537 # if HAVE_GIFERRORSTRING
7538 DEF_DLL_FN (char const *, GifErrorString
, (int));
7542 init_gif_functions (void)
7546 if (!(library
= w32_delayed_load (Qgif
)))
7549 LOAD_DLL_FN (library
, DGifCloseFile
);
7550 LOAD_DLL_FN (library
, DGifSlurp
);
7551 LOAD_DLL_FN (library
, DGifOpen
);
7552 LOAD_DLL_FN (library
, DGifOpenFileName
);
7553 # if HAVE_GIFERRORSTRING
7554 LOAD_DLL_FN (library
, GifErrorString
);
7559 # undef DGifCloseFile
7561 # undef DGifOpenFileName
7563 # undef GifErrorString
7565 # define DGifCloseFile fn_DGifCloseFile
7566 # define DGifOpen fn_DGifOpen
7567 # define DGifOpenFileName fn_DGifOpenFileName
7568 # define DGifSlurp fn_DGifSlurp
7569 # define GifErrorString fn_GifErrorString
7571 # endif /* WINDOWSNT */
7573 /* Reading a GIF image from memory
7574 Based on the PNG memory stuff to a certain extent. */
7578 unsigned char *bytes
;
7584 /* Make the current memory source available to gif_read_from_memory.
7585 It's done this way because not all versions of libungif support
7586 a UserData field in the GifFileType structure. */
7587 static gif_memory_source
*current_gif_memory_src
;
7590 gif_read_from_memory (GifFileType
*file
, GifByteType
*buf
, int len
)
7592 gif_memory_source
*src
= current_gif_memory_src
;
7594 if (len
> src
->len
- src
->index
)
7597 memcpy (buf
, src
->bytes
+ src
->index
, len
);
7603 gif_close (GifFileType
*gif
, int *err
)
7607 #if GIFLIB_MAJOR + (GIFLIB_MINOR >= 1) > 5
7608 retval
= DGifCloseFile (gif
, err
);
7610 retval
= DGifCloseFile (gif
);
7611 #if GIFLIB_MAJOR >= 5
7619 /* Load GIF image IMG for use on frame F. Value is true if
7622 static const int interlace_start
[] = {0, 4, 2, 1};
7623 static const int interlace_increment
[] = {8, 8, 4, 2};
7625 #define GIF_LOCAL_DESCRIPTOR_EXTENSION 249
7628 gif_load (struct frame
*f
, struct image
*img
)
7630 int rc
, width
, height
, x
, y
, i
, j
;
7631 ColorMapObject
*gif_color_map
;
7633 gif_memory_source memsrc
;
7634 Lisp_Object specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
7635 Lisp_Object specified_file
= image_spec_value (img
->spec
, QCfile
, NULL
);
7636 Lisp_Object specified_data
= image_spec_value (img
->spec
, QCdata
, NULL
);
7641 unsigned char *data
= 0;
7643 unsigned long pixel_colors
[256];
7644 unsigned long bgcolor
= 0;
7648 if (NILP (specified_data
))
7650 Lisp_Object file
= x_find_image_file (specified_file
);
7651 if (!STRINGP (file
))
7653 image_error ("Cannot find image file `%s'", specified_file
);
7657 Lisp_Object encoded_file
= ENCODE_FILE (file
);
7659 encoded_file
= ansi_encode_filename (encoded_file
);
7662 /* Open the GIF file. */
7663 #if GIFLIB_MAJOR < 5
7664 gif
= DGifOpenFileName (SSDATA (encoded_file
));
7666 gif
= DGifOpenFileName (SSDATA (encoded_file
), &gif_err
);
7670 #if HAVE_GIFERRORSTRING
7671 image_error ("Cannot open `%s': %s",
7672 file
, build_string (GifErrorString (gif_err
)));
7674 image_error ("Cannot open `%s'", file
);
7681 if (!STRINGP (specified_data
))
7683 image_error ("Invalid image data `%s'", specified_data
);
7687 /* Read from memory! */
7688 current_gif_memory_src
= &memsrc
;
7689 memsrc
.bytes
= SDATA (specified_data
);
7690 memsrc
.len
= SBYTES (specified_data
);
7693 #if GIFLIB_MAJOR < 5
7694 gif
= DGifOpen (&memsrc
, gif_read_from_memory
);
7696 gif
= DGifOpen (&memsrc
, gif_read_from_memory
, &gif_err
);
7700 #if HAVE_GIFERRORSTRING
7701 image_error ("Cannot open memory source `%s': %s",
7702 img
->spec
, build_string (GifErrorString (gif_err
)));
7704 image_error ("Cannot open memory source `%s'", img
->spec
);
7710 /* Before reading entire contents, check the declared image size. */
7711 if (!check_image_size (f
, gif
->SWidth
, gif
->SHeight
))
7713 image_size_error ();
7714 gif_close (gif
, NULL
);
7718 /* Read entire contents. */
7719 rc
= DGifSlurp (gif
);
7720 if (rc
== GIF_ERROR
|| gif
->ImageCount
<= 0)
7722 image_error ("Error reading `%s'", img
->spec
);
7723 gif_close (gif
, NULL
);
7727 /* Which sub-image are we to display? */
7729 Lisp_Object image_number
= image_spec_value (img
->spec
, QCindex
, NULL
);
7730 idx
= INTEGERP (image_number
) ? XFASTINT (image_number
) : 0;
7731 if (idx
< 0 || idx
>= gif
->ImageCount
)
7733 image_error ("Invalid image number `%s' in image `%s'",
7734 image_number
, img
->spec
);
7735 gif_close (gif
, NULL
);
7740 width
= img
->width
= gif
->SWidth
;
7741 height
= img
->height
= gif
->SHeight
;
7743 img
->corners
[TOP_CORNER
] = gif
->SavedImages
[0].ImageDesc
.Top
;
7744 img
->corners
[LEFT_CORNER
] = gif
->SavedImages
[0].ImageDesc
.Left
;
7745 img
->corners
[BOT_CORNER
]
7746 = img
->corners
[TOP_CORNER
] + gif
->SavedImages
[0].ImageDesc
.Height
;
7747 img
->corners
[RIGHT_CORNER
]
7748 = img
->corners
[LEFT_CORNER
] + gif
->SavedImages
[0].ImageDesc
.Width
;
7750 if (!check_image_size (f
, width
, height
))
7752 image_size_error ();
7753 gif_close (gif
, NULL
);
7757 /* Check that the selected subimages fit. It's not clear whether
7758 the GIF spec requires this, but Emacs can crash if they don't fit. */
7759 for (j
= 0; j
<= idx
; ++j
)
7761 struct SavedImage
*subimage
= gif
->SavedImages
+ j
;
7762 int subimg_width
= subimage
->ImageDesc
.Width
;
7763 int subimg_height
= subimage
->ImageDesc
.Height
;
7764 int subimg_top
= subimage
->ImageDesc
.Top
;
7765 int subimg_left
= subimage
->ImageDesc
.Left
;
7766 if (! (subimg_width
>= 0 && subimg_height
>= 0
7767 && 0 <= subimg_top
&& subimg_top
<= height
- subimg_height
7768 && 0 <= subimg_left
&& subimg_left
<= width
- subimg_width
))
7770 image_error ("Subimage does not fit in image");
7771 gif_close (gif
, NULL
);
7777 /* xzalloc so data is zero => transparent */
7778 data
= (unsigned char *) xzalloc (width
* height
* 4);
7779 if (STRINGP (specified_bg
))
7782 if (x_defined_color (f
, SSDATA (specified_bg
), &color
, 0))
7784 uint32_t *dataptr
= (uint32_t *)data
;
7785 int r
= color
.red
/256;
7786 int g
= color
.green
/256;
7787 int b
= color
.blue
/256;
7789 for (y
= 0; y
< height
; ++y
)
7790 for (x
= 0; x
< width
; ++x
)
7791 *dataptr
++ = (0xff << 24) | (r
<< 16) | (g
<< 8) | b
;
7795 /* Create the X image and pixmap. */
7796 if (!image_create_x_image_and_pixmap (f
, img
, width
, height
, 0, &ximg
, 0))
7798 gif_close (gif
, NULL
);
7802 /* Clear the part of the screen image not covered by the image.
7803 Full animated GIF support requires more here (see the gif89 spec,
7804 disposal methods). Let's simply assume that the part not covered
7805 by a sub-image is in the frame's background color. */
7806 for (y
= 0; y
< img
->corners
[TOP_CORNER
]; ++y
)
7807 for (x
= 0; x
< width
; ++x
)
7808 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7810 for (y
= img
->corners
[BOT_CORNER
]; y
< height
; ++y
)
7811 for (x
= 0; x
< width
; ++x
)
7812 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7814 for (y
= img
->corners
[TOP_CORNER
]; y
< img
->corners
[BOT_CORNER
]; ++y
)
7816 for (x
= 0; x
< img
->corners
[LEFT_CORNER
]; ++x
)
7817 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7818 for (x
= img
->corners
[RIGHT_CORNER
]; x
< width
; ++x
)
7819 XPutPixel (ximg
, x
, y
, FRAME_BACKGROUND_PIXEL (f
));
7823 /* Read the GIF image into the X image. */
7825 /* FIXME: With the current implementation, loading an animated gif
7826 is quadratic in the number of animation frames, since each frame
7827 is a separate struct image. We must provide a way for a single
7828 gif_load call to construct and save all animation frames. */
7830 init_color_table ();
7833 if (STRINGP (specified_bg
))
7834 bgcolor
= x_alloc_image_color (f
, img
, specified_bg
,
7835 FRAME_BACKGROUND_PIXEL (f
));
7838 for (j
= 0; j
<= idx
; ++j
)
7840 /* We use a local variable `raster' here because RasterBits is a
7841 char *, which invites problems with bytes >= 0x80. */
7842 struct SavedImage
*subimage
= gif
->SavedImages
+ j
;
7843 unsigned char *raster
= (unsigned char *) subimage
->RasterBits
;
7844 int transparency_color_index
= -1;
7846 int subimg_width
= subimage
->ImageDesc
.Width
;
7847 int subimg_height
= subimage
->ImageDesc
.Height
;
7848 int subimg_top
= subimage
->ImageDesc
.Top
;
7849 int subimg_left
= subimage
->ImageDesc
.Left
;
7851 /* Find the Graphic Control Extension block for this sub-image.
7852 Extract the disposal method and transparency color. */
7853 for (i
= 0; i
< subimage
->ExtensionBlockCount
; i
++)
7855 ExtensionBlock
*extblock
= subimage
->ExtensionBlocks
+ i
;
7857 if ((extblock
->Function
== GIF_LOCAL_DESCRIPTOR_EXTENSION
)
7858 && extblock
->ByteCount
== 4
7859 && extblock
->Bytes
[0] & 1)
7861 /* From gif89a spec: 1 = "keep in place", 2 = "restore
7862 to background". Treat any other value like 2. */
7863 disposal
= (extblock
->Bytes
[0] >> 2) & 7;
7864 transparency_color_index
= (unsigned char) extblock
->Bytes
[3];
7869 /* We can't "keep in place" the first subimage. */
7873 /* For disposal == 0, the spec says "No disposal specified. The
7874 decoder is not required to take any action." In practice, it
7875 seems we need to treat this like "keep in place", see e.g.
7876 http://upload.wikimedia.org/wikipedia/commons/3/37/Clock.gif */
7880 gif_color_map
= subimage
->ImageDesc
.ColorMap
;
7882 gif_color_map
= gif
->SColorMap
;
7885 /* Allocate subimage colors. */
7886 memset (pixel_colors
, 0, sizeof pixel_colors
);
7889 for (i
= 0; i
< gif_color_map
->ColorCount
; ++i
)
7891 if (transparency_color_index
== i
)
7892 pixel_colors
[i
] = STRINGP (specified_bg
)
7893 ? bgcolor
: FRAME_BACKGROUND_PIXEL (f
);
7896 int r
= gif_color_map
->Colors
[i
].Red
<< 8;
7897 int g
= gif_color_map
->Colors
[i
].Green
<< 8;
7898 int b
= gif_color_map
->Colors
[i
].Blue
<< 8;
7899 pixel_colors
[i
] = lookup_rgb_color (f
, r
, g
, b
);
7904 /* Apply the pixel values. */
7905 if (GIFLIB_MAJOR
< 5 && gif
->SavedImages
[j
].ImageDesc
.Interlace
)
7909 for (y
= 0, row
= interlace_start
[0], pass
= 0;
7911 y
++, row
+= interlace_increment
[pass
])
7913 while (subimg_height
<= row
)
7914 row
= interlace_start
[++pass
];
7916 for (x
= 0; x
< subimg_width
; x
++)
7918 int c
= raster
[y
* subimg_width
+ x
];
7919 if (transparency_color_index
!= c
|| disposal
!= 1)
7923 ((uint32_t*)data
+ ((row
+ subimg_top
) * subimg_width
7924 + x
+ subimg_left
));
7925 int r
= gif_color_map
->Colors
[c
].Red
;
7926 int g
= gif_color_map
->Colors
[c
].Green
;
7927 int b
= gif_color_map
->Colors
[c
].Blue
;
7929 if (transparency_color_index
!= c
)
7930 *dataptr
= (0xff << 24) | (r
<< 16) | (g
<< 8) | b
;
7932 XPutPixel (ximg
, x
+ subimg_left
, row
+ subimg_top
,
7941 for (y
= 0; y
< subimg_height
; ++y
)
7942 for (x
= 0; x
< subimg_width
; ++x
)
7944 int c
= raster
[y
* subimg_width
+ x
];
7945 if (transparency_color_index
!= c
|| disposal
!= 1)
7949 ((uint32_t*)data
+ ((y
+ subimg_top
) * subimg_width
7950 + x
+ subimg_left
));
7951 int r
= gif_color_map
->Colors
[c
].Red
;
7952 int g
= gif_color_map
->Colors
[c
].Green
;
7953 int b
= gif_color_map
->Colors
[c
].Blue
;
7954 if (transparency_color_index
!= c
)
7955 *dataptr
= (0xff << 24) | (r
<< 16) | (g
<< 8) | b
;
7957 XPutPixel (ximg
, x
+ subimg_left
, y
+ subimg_top
,
7965 #ifdef COLOR_TABLE_SUPPORT
7966 img
->colors
= colors_in_color_table (&img
->ncolors
);
7967 free_color_table ();
7968 #endif /* COLOR_TABLE_SUPPORT */
7970 /* Save GIF image extension data for `image-metadata'.
7971 Format is (count IMAGES extension-data (FUNCTION "BYTES" ...)). */
7972 img
->lisp_data
= Qnil
;
7973 if (gif
->SavedImages
[idx
].ExtensionBlockCount
> 0)
7976 ExtensionBlock
*ext
= gif
->SavedImages
[idx
].ExtensionBlocks
;
7977 for (i
= 0; i
< gif
->SavedImages
[idx
].ExtensionBlockCount
; i
++, ext
++)
7978 /* Append (... FUNCTION "BYTES") */
7981 = Fcons (make_number (ext
->Function
),
7982 Fcons (make_unibyte_string (ext
->Bytes
, ext
->ByteCount
),
7984 if (ext
->Function
== GIF_LOCAL_DESCRIPTOR_EXTENSION
7985 && ext
->ByteCount
== 4)
7987 delay
= ext
->Bytes
[2] << CHAR_BIT
;
7988 delay
|= ext
->Bytes
[1];
7991 img
->lisp_data
= list2 (Qextension_data
, img
->lisp_data
);
7995 Fcons (make_float (delay
/ 100.0),
7999 if (gif
->ImageCount
> 1)
8000 img
->lisp_data
= Fcons (Qcount
,
8001 Fcons (make_number (gif
->ImageCount
),
8004 if (gif_close (gif
, &gif_err
) == GIF_ERROR
)
8006 #if HAVE_GIFERRORSTRING
8007 char const *error_text
= GifErrorString (gif_err
);
8010 image_error ("Error closing `%s': %s",
8011 img
->spec
, build_string (error_text
));
8013 image_error ("Error closing `%s'", img
->spec
);
8018 create_cairo_image_surface (img
, data
, width
, height
);
8020 /* Maybe fill in the background field while we have ximg handy. */
8021 if (NILP (image_spec_value (img
->spec
, QCbackground
, NULL
)))
8022 /* Casting avoids a GCC warning. */
8023 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
8025 /* Put ximg into the image. */
8026 image_put_x_image (f
, img
, ximg
, 0);
8032 #else /* !HAVE_GIF */
8036 gif_load (struct frame
*f
, struct image
*img
)
8038 return ns_load_image (f
, img
,
8039 image_spec_value (img
->spec
, QCfile
, NULL
),
8040 image_spec_value (img
->spec
, QCdata
, NULL
));
8042 #endif /* HAVE_NS */
8044 #endif /* HAVE_GIF */
8047 #ifdef HAVE_IMAGEMAGICK
8049 /***********************************************************************
8051 ***********************************************************************/
8053 /* Scale an image size by returning SIZE / DIVISOR * MULTIPLIER,
8054 safely rounded and clipped to int range. */
8057 scale_image_size (int size
, size_t divisor
, size_t multiplier
)
8062 double scaled
= s
* multiplier
/ divisor
+ 0.5;
8063 if (scaled
< INT_MAX
)
8069 /* Compute the desired size of an image with native size WIDTH x HEIGHT.
8070 Use SPEC to deduce the size. Store the desired size into
8071 *D_WIDTH x *D_HEIGHT. Store -1 x -1 if the native size is OK. */
8073 compute_image_size (size_t width
, size_t height
,
8075 int *d_width
, int *d_height
)
8078 int desired_width
, desired_height
;
8080 /* If width and/or height is set in the display spec assume we want
8081 to scale to those values. If either h or w is unspecified, the
8082 unspecified should be calculated from the specified to preserve
8084 value
= image_spec_value (spec
, QCwidth
, NULL
);
8085 desired_width
= NATNUMP (value
) ? min (XFASTINT (value
), INT_MAX
) : -1;
8086 value
= image_spec_value (spec
, QCheight
, NULL
);
8087 desired_height
= NATNUMP (value
) ? min (XFASTINT (value
), INT_MAX
) : -1;
8089 if (desired_width
== -1)
8091 value
= image_spec_value (spec
, QCmax_width
, NULL
);
8092 if (NATNUMP (value
))
8094 int max_width
= min (XFASTINT (value
), INT_MAX
);
8095 if (max_width
< width
)
8097 /* The image is wider than :max-width. */
8098 desired_width
= max_width
;
8099 if (desired_height
== -1)
8101 desired_height
= scale_image_size (desired_width
,
8103 value
= image_spec_value (spec
, QCmax_height
, NULL
);
8104 if (NATNUMP (value
))
8106 int max_height
= min (XFASTINT (value
), INT_MAX
);
8107 if (max_height
< desired_height
)
8109 desired_height
= max_height
;
8110 desired_width
= scale_image_size (desired_height
,
8119 if (desired_height
== -1)
8121 value
= image_spec_value (spec
, QCmax_height
, NULL
);
8122 if (NATNUMP (value
))
8124 int max_height
= min (XFASTINT (value
), INT_MAX
);
8125 if (max_height
< height
)
8126 desired_height
= max_height
;
8130 if (desired_width
!= -1 && desired_height
== -1)
8131 /* w known, calculate h. */
8132 desired_height
= scale_image_size (desired_width
, width
, height
);
8134 if (desired_width
== -1 && desired_height
!= -1)
8135 /* h known, calculate w. */
8136 desired_width
= scale_image_size (desired_height
, height
, width
);
8138 *d_width
= desired_width
;
8139 *d_height
= desired_height
;
8142 static bool imagemagick_image_p (Lisp_Object
);
8143 static bool imagemagick_load (struct frame
*, struct image
*);
8144 static void imagemagick_clear_image (struct frame
*, struct image
*);
8146 /* Indices of image specification fields in imagemagick_format. */
8148 enum imagemagick_keyword_index
8156 IMAGEMAGICK_ALGORITHM
,
8157 IMAGEMAGICK_HEURISTIC_MASK
,
8159 IMAGEMAGICK_BACKGROUND
,
8162 IMAGEMAGICK_MAX_HEIGHT
,
8163 IMAGEMAGICK_MAX_WIDTH
,
8165 IMAGEMAGICK_ROTATION
,
8170 /* Vector of image_keyword structures describing the format
8171 of valid user-defined image specifications. */
8173 static struct image_keyword imagemagick_format
[IMAGEMAGICK_LAST
] =
8175 {":type", IMAGE_SYMBOL_VALUE
, 1},
8176 {":data", IMAGE_STRING_VALUE
, 0},
8177 {":file", IMAGE_STRING_VALUE
, 0},
8178 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8179 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
8180 {":relief", IMAGE_INTEGER_VALUE
, 0},
8181 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8182 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8183 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8184 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0},
8185 {":height", IMAGE_INTEGER_VALUE
, 0},
8186 {":width", IMAGE_INTEGER_VALUE
, 0},
8187 {":max-height", IMAGE_INTEGER_VALUE
, 0},
8188 {":max-width", IMAGE_INTEGER_VALUE
, 0},
8189 {":format", IMAGE_SYMBOL_VALUE
, 0},
8190 {":rotation", IMAGE_NUMBER_VALUE
, 0},
8191 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE
, 0}
8194 #if defined HAVE_NTGUI && defined WINDOWSNT
8195 static bool init_imagemagick_functions (void);
8197 #define init_imagemagick_functions NULL
8200 /* Structure describing the image type for any image handled via
8203 static struct image_type imagemagick_type
=
8205 SYMBOL_INDEX (Qimagemagick
),
8206 imagemagick_image_p
,
8208 imagemagick_clear_image
,
8209 init_imagemagick_functions
,
8213 /* Free X resources of imagemagick image IMG which is used on frame F. */
8216 imagemagick_clear_image (struct frame
*f
,
8219 x_clear_image (f
, img
);
8222 /* Return true if OBJECT is a valid IMAGEMAGICK image specification. Do
8223 this by calling parse_image_spec and supplying the keywords that
8224 identify the IMAGEMAGICK format. */
8227 imagemagick_image_p (Lisp_Object object
)
8229 struct image_keyword fmt
[IMAGEMAGICK_LAST
];
8230 memcpy (fmt
, imagemagick_format
, sizeof fmt
);
8232 if (!parse_image_spec (object
, fmt
, IMAGEMAGICK_LAST
, Qimagemagick
))
8235 /* Must specify either the :data or :file keyword. */
8236 return fmt
[IMAGEMAGICK_FILE
].count
+ fmt
[IMAGEMAGICK_DATA
].count
== 1;
8239 /* The GIF library also defines DrawRectangle, but its never used in Emacs.
8240 Therefore rename the function so it doesn't collide with ImageMagick. */
8241 #define DrawRectangle DrawRectangleGif
8242 #include <wand/MagickWand.h>
8244 /* ImageMagick 6.5.3 through 6.6.5 hid PixelGetMagickColor for some reason.
8245 Emacs seems to work fine with the hidden version, so unhide it. */
8246 #include <magick/version.h>
8247 #if 0x653 <= MagickLibVersion && MagickLibVersion <= 0x665
8248 extern WandExport
void PixelGetMagickColor (const PixelWand
*,
8249 MagickPixelPacket
*);
8252 /* Log ImageMagick error message.
8253 Useful when a ImageMagick function returns the status `MagickFalse'. */
8256 imagemagick_error (MagickWand
*wand
)
8259 ExceptionType severity
;
8261 description
= MagickGetException (wand
, &severity
);
8262 image_error ("ImageMagick error: %s", build_string (description
));
8263 MagickRelinquishMemory (description
);
8266 /* Possibly give ImageMagick some extra help to determine the image
8267 type by supplying a "dummy" filename based on the Content-Type. */
8270 imagemagick_filename_hint (Lisp_Object spec
, char hint_buffer
[MaxTextExtent
])
8272 Lisp_Object symbol
= intern ("image-format-suffixes");
8273 Lisp_Object val
= find_symbol_value (symbol
);
8279 format
= image_spec_value (spec
, intern (":format"), NULL
);
8280 val
= Fcar_safe (Fcdr_safe (Fassq (format
, val
)));
8281 if (! STRINGP (val
))
8284 /* It's OK to truncate the hint if it has MaxTextExtent or more bytes,
8285 as ImageMagick would ignore the extra bytes anyway. */
8286 snprintf (hint_buffer
, MaxTextExtent
, "/tmp/foo.%s", SSDATA (val
));
8290 /* Animated images (e.g., GIF89a) are composed from one "master image"
8291 (which is the first one, and then there's a number of images that
8292 follow. If following images have non-transparent colors, these are
8293 composed "on top" of the master image. So, in general, one has to
8294 compute ann the preceding images to be able to display a particular
8297 Computing all the preceding images is too slow, so we maintain a
8298 cache of previously computed images. We have to maintain a cache
8299 separate from the image cache, because the images may be scaled
8302 struct animation_cache
8306 struct timespec update_time
;
8307 struct animation_cache
*next
;
8308 char signature
[FLEXIBLE_ARRAY_MEMBER
];
8311 static struct animation_cache
*animation_cache
= NULL
;
8313 static struct animation_cache
*
8314 imagemagick_create_cache (char *signature
)
8316 struct animation_cache
*cache
8317 = xmalloc (offsetof (struct animation_cache
, signature
)
8318 + strlen (signature
) + 1);
8322 strcpy (cache
->signature
, signature
);
8326 /* Discard cached images that haven't been used for a minute. */
8328 imagemagick_prune_animation_cache (void)
8330 struct animation_cache
**pcache
= &animation_cache
;
8331 struct timespec old
= timespec_sub (current_timespec (),
8332 make_timespec (60, 0));
8336 struct animation_cache
*cache
= *pcache
;
8337 if (timespec_cmp (old
, cache
->update_time
) <= 0)
8338 pcache
= &cache
->next
;
8342 DestroyMagickWand (cache
->wand
);
8343 *pcache
= cache
->next
;
8349 static struct animation_cache
*
8350 imagemagick_get_animation_cache (MagickWand
*wand
)
8352 char *signature
= MagickGetImageSignature (wand
);
8353 struct animation_cache
*cache
;
8354 struct animation_cache
**pcache
= &animation_cache
;
8356 imagemagick_prune_animation_cache ();
8363 *pcache
= cache
= imagemagick_create_cache (signature
);
8366 if (strcmp (signature
, cache
->signature
) == 0)
8368 pcache
= &cache
->next
;
8371 DestroyString (signature
);
8372 cache
->update_time
= current_timespec ();
8377 imagemagick_compute_animated_image (MagickWand
*super_wand
, int ino
)
8380 MagickWand
*composite_wand
;
8381 size_t dest_width
, dest_height
;
8382 struct animation_cache
*cache
= imagemagick_get_animation_cache (super_wand
);
8384 MagickSetIteratorIndex (super_wand
, 0);
8386 if (ino
== 0 || cache
->wand
== NULL
|| cache
->index
> ino
)
8388 composite_wand
= MagickGetImage (super_wand
);
8390 DestroyMagickWand (cache
->wand
);
8393 composite_wand
= cache
->wand
;
8395 dest_height
= MagickGetImageHeight (composite_wand
);
8397 for (i
= max (1, cache
->index
+ 1); i
<= ino
; i
++)
8399 MagickWand
*sub_wand
;
8400 PixelIterator
*source_iterator
, *dest_iterator
;
8401 PixelWand
**source
, **dest
;
8402 size_t source_width
, source_height
;
8403 ssize_t source_left
, source_top
;
8404 MagickPixelPacket pixel
;
8405 DisposeType dispose
;
8406 ptrdiff_t lines
= 0;
8408 MagickSetIteratorIndex (super_wand
, i
);
8409 sub_wand
= MagickGetImage (super_wand
);
8411 MagickGetImagePage (sub_wand
, &source_width
, &source_height
,
8412 &source_left
, &source_top
);
8414 /* This flag says how to handle transparent pixels. */
8415 dispose
= MagickGetImageDispose (sub_wand
);
8417 source_iterator
= NewPixelIterator (sub_wand
);
8418 if (! source_iterator
)
8420 DestroyMagickWand (composite_wand
);
8421 DestroyMagickWand (sub_wand
);
8423 image_error ("Imagemagick pixel iterator creation failed");
8427 dest_iterator
= NewPixelIterator (composite_wand
);
8428 if (! dest_iterator
)
8430 DestroyMagickWand (composite_wand
);
8431 DestroyMagickWand (sub_wand
);
8432 DestroyPixelIterator (source_iterator
);
8434 image_error ("Imagemagick pixel iterator creation failed");
8438 /* The sub-image may not start at origin, so move the destination
8439 iterator to where the sub-image should start. */
8442 PixelSetIteratorRow (dest_iterator
, source_top
);
8446 while ((source
= PixelGetNextIteratorRow (source_iterator
, &source_width
))
8451 /* Sanity check. This shouldn't happen, but apparently
8452 does in some pictures. */
8453 if (++lines
>= dest_height
)
8456 dest
= PixelGetNextIteratorRow (dest_iterator
, &dest_width
);
8457 for (x
= 0; x
< source_width
; x
++)
8459 /* Sanity check. This shouldn't happen, but apparently
8460 also does in some pictures. */
8461 if (x
+ source_left
>= dest_width
)
8463 /* Normally we only copy over non-transparent pixels,
8464 but if the disposal method is "Background", then we
8465 copy over all pixels. */
8466 if (dispose
== BackgroundDispose
|| PixelGetAlpha (source
[x
]))
8468 PixelGetMagickColor (source
[x
], &pixel
);
8469 PixelSetMagickColor (dest
[x
+ source_left
], &pixel
);
8472 PixelSyncIterator (dest_iterator
);
8475 DestroyPixelIterator (source_iterator
);
8476 DestroyPixelIterator (dest_iterator
);
8477 DestroyMagickWand (sub_wand
);
8480 /* Cache a copy for the next iteration. The current wand will be
8481 destroyed by the caller. */
8482 cache
->wand
= CloneMagickWand (composite_wand
);
8485 return composite_wand
;
8489 /* Helper function for imagemagick_load, which does the actual loading
8490 given contents and size, apart from frame and image structures,
8491 passed from imagemagick_load. Uses librimagemagick to do most of
8492 the image processing.
8494 F is a pointer to the Emacs frame; IMG to the image structure to
8495 prepare; CONTENTS is the string containing the IMAGEMAGICK data to
8496 be parsed; SIZE is the number of bytes of data; and FILENAME is
8497 either the file name or the image data.
8499 Return true if successful. */
8502 imagemagick_load_image (struct frame
*f
, struct image
*img
,
8503 unsigned char *contents
, unsigned int size
,
8507 size_t image_width
, image_height
;
8508 MagickBooleanType status
;
8511 MagickWand
*image_wand
;
8512 PixelIterator
*iterator
;
8513 PixelWand
**pixels
, *bg_wand
= NULL
;
8514 MagickPixelPacket pixel
;
8519 int desired_width
, desired_height
;
8522 char hint_buffer
[MaxTextExtent
];
8523 char *filename_hint
= NULL
;
8525 /* Handle image index for image types who can contain more than one image.
8526 Interface :index is same as for GIF. First we "ping" the image to see how
8527 many sub-images it contains. Pinging is faster than loading the image to
8528 find out things about it. */
8530 /* Initialize the imagemagick environment. */
8531 MagickWandGenesis ();
8532 image
= image_spec_value (img
->spec
, QCindex
, NULL
);
8533 ino
= INTEGERP (image
) ? XFASTINT (image
) : 0;
8534 image_wand
= NewMagickWand ();
8537 status
= MagickReadImage (image_wand
, filename
);
8540 filename_hint
= imagemagick_filename_hint (img
->spec
, hint_buffer
);
8541 MagickSetFilename (image_wand
, filename_hint
);
8542 status
= MagickReadImageBlob (image_wand
, contents
, size
);
8545 if (status
== MagickFalse
)
8547 imagemagick_error (image_wand
);
8548 DestroyMagickWand (image_wand
);
8552 if (ino
< 0 || ino
>= MagickGetNumberImages (image_wand
))
8554 image_error ("Invalid image number `%s' in image `%s'", image
, img
->spec
);
8555 DestroyMagickWand (image_wand
);
8559 if (MagickGetImageDelay (image_wand
) > 0)
8562 Fcons (make_float (MagickGetImageDelay (image_wand
) / 100.0),
8565 if (MagickGetNumberImages (image_wand
) > 1)
8568 Fcons (make_number (MagickGetNumberImages (image_wand
)),
8571 /* If we have an animated image, get the new wand based on the
8573 if (MagickGetNumberImages (image_wand
) > 1)
8575 MagickWand
*super_wand
= image_wand
;
8576 image_wand
= imagemagick_compute_animated_image (super_wand
, ino
);
8578 image_wand
= super_wand
;
8580 DestroyMagickWand (super_wand
);
8583 /* Retrieve the frame's background color, for use later. */
8586 Lisp_Object specified_bg
;
8588 specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
8589 if (!STRINGP (specified_bg
)
8590 || !x_defined_color (f
, SSDATA (specified_bg
), &bgcolor
, 0))
8591 x_query_frame_background_color (f
, &bgcolor
);
8593 bg_wand
= NewPixelWand ();
8594 PixelSetRed (bg_wand
, (double) bgcolor
.red
/ 65535);
8595 PixelSetGreen (bg_wand
, (double) bgcolor
.green
/ 65535);
8596 PixelSetBlue (bg_wand
, (double) bgcolor
.blue
/ 65535);
8599 compute_image_size (MagickGetImageWidth (image_wand
),
8600 MagickGetImageHeight (image_wand
),
8601 img
->spec
, &desired_width
, &desired_height
);
8603 if (desired_width
!= -1 && desired_height
!= -1)
8605 status
= MagickScaleImage (image_wand
, desired_width
, desired_height
);
8606 if (status
== MagickFalse
)
8608 image_error ("Imagemagick scale failed");
8609 imagemagick_error (image_wand
);
8610 goto imagemagick_error
;
8614 /* crop behaves similar to image slicing in Emacs but is more memory
8616 crop
= image_spec_value (img
->spec
, QCcrop
, NULL
);
8618 if (CONSP (crop
) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop
)))
8620 /* After some testing, it seems MagickCropImage is the fastest crop
8621 function in ImageMagick. This crop function seems to do less copying
8622 than the alternatives, but it still reads the entire image into memory
8623 before cropping, which is apparently difficult to avoid when using
8625 size_t crop_width
= XINT (XCAR (crop
));
8627 if (CONSP (crop
) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop
)))
8629 size_t crop_height
= XINT (XCAR (crop
));
8631 if (CONSP (crop
) && TYPE_RANGED_INTEGERP (ssize_t
, XCAR (crop
)))
8633 ssize_t crop_x
= XINT (XCAR (crop
));
8635 if (CONSP (crop
) && TYPE_RANGED_INTEGERP (ssize_t
, XCAR (crop
)))
8637 ssize_t crop_y
= XINT (XCAR (crop
));
8638 MagickCropImage (image_wand
, crop_width
, crop_height
,
8645 /* Furthermore :rotation. we need background color and angle for
8648 TODO background handling for rotation specified_bg =
8649 image_spec_value (img->spec, QCbackground, NULL); if (!STRINGP
8651 value
= image_spec_value (img
->spec
, QCrotation
, NULL
);
8654 rotation
= extract_float (value
);
8655 status
= MagickRotateImage (image_wand
, bg_wand
, rotation
);
8656 if (status
== MagickFalse
)
8658 image_error ("Imagemagick image rotate failed");
8659 imagemagick_error (image_wand
);
8660 goto imagemagick_error
;
8664 /* Set the canvas background color to the frame or specified
8665 background, and flatten the image. Note: as of ImageMagick
8666 6.6.0, SVG image transparency is not handled properly
8667 (e.g. etc/images/splash.svg shows a white background always). */
8669 MagickWand
*new_wand
;
8670 MagickSetImageBackgroundColor (image_wand
, bg_wand
);
8671 #ifdef HAVE_MAGICKMERGEIMAGELAYERS
8672 new_wand
= MagickMergeImageLayers (image_wand
, MergeLayer
);
8674 new_wand
= MagickFlattenImages (image_wand
);
8676 DestroyMagickWand (image_wand
);
8677 image_wand
= new_wand
;
8680 /* Finally we are done manipulating the image. Figure out the
8681 resulting width/height and transfer ownership to Emacs. */
8682 image_height
= MagickGetImageHeight (image_wand
);
8683 image_width
= MagickGetImageWidth (image_wand
);
8685 if (! (image_width
<= INT_MAX
&& image_height
<= INT_MAX
8686 && check_image_size (f
, image_width
, image_height
)))
8688 image_size_error ();
8689 goto imagemagick_error
;
8692 width
= image_width
;
8693 height
= image_height
;
8695 /* We can now get a valid pixel buffer from the imagemagick file, if all
8698 init_color_table ();
8700 #if defined (HAVE_MAGICKEXPORTIMAGEPIXELS) && ! defined (HAVE_NS)
8701 if (imagemagick_render_type
!= 0)
8703 /* Magicexportimage is normally faster than pixelpushing. This
8704 method is also well tested. Some aspects of this method are
8705 ad-hoc and needs to be more researched. */
8706 int imagedepth
= 24; /*MagickGetImageDepth(image_wand);*/
8707 const char *exportdepth
= imagedepth
<= 8 ? "I" : "BGRP"; /*"RGBP";*/
8708 /* Try to create a x pixmap to hold the imagemagick pixmap. */
8709 if (!image_create_x_image_and_pixmap (f
, img
, width
, height
, imagedepth
,
8712 #ifdef COLOR_TABLE_SUPPORT
8713 free_color_table ();
8715 image_error ("Imagemagick X bitmap allocation failure");
8716 goto imagemagick_error
;
8719 /* Oddly, the below code doesn't seem to work:*/
8720 /* switch(ximg->bitmap_unit){ */
8722 /* pixelwidth=CharPixel; */
8725 /* pixelwidth=ShortPixel; */
8728 /* pixelwidth=LongPixel; */
8732 Here im just guessing the format of the bitmap.
8733 happens to work fine for:
8736 seems about 3 times as fast as pixel pushing(not carefully measured)
8738 pixelwidth
= CharPixel
; /*??? TODO figure out*/
8739 MagickExportImagePixels (image_wand
, 0, 0, width
, height
,
8740 exportdepth
, pixelwidth
, ximg
->data
);
8743 #endif /* HAVE_MAGICKEXPORTIMAGEPIXELS */
8745 size_t image_height
;
8746 MagickRealType color_scale
= 65535.0 / QuantumRange
;
8748 /* Try to create a x pixmap to hold the imagemagick pixmap. */
8749 if (!image_create_x_image_and_pixmap (f
, img
, width
, height
, 0,
8752 #ifdef COLOR_TABLE_SUPPORT
8753 free_color_table ();
8755 image_error ("Imagemagick X bitmap allocation failure");
8756 goto imagemagick_error
;
8759 /* Copy imagemagick image to x with primitive yet robust pixel
8760 pusher loop. This has been tested a lot with many different
8763 /* Copy pixels from the imagemagick image structure to the x image map. */
8764 iterator
= NewPixelIterator (image_wand
);
8767 #ifdef COLOR_TABLE_SUPPORT
8768 free_color_table ();
8770 x_destroy_x_image (ximg
);
8771 image_error ("Imagemagick pixel iterator creation failed");
8772 goto imagemagick_error
;
8775 image_height
= MagickGetImageHeight (image_wand
);
8776 for (y
= 0; y
< image_height
; y
++)
8779 pixels
= PixelGetNextIteratorRow (iterator
, &row_width
);
8782 int xlim
= min (row_width
, width
);
8783 for (x
= 0; x
< xlim
; x
++)
8785 PixelGetMagickColor (pixels
[x
], &pixel
);
8786 XPutPixel (ximg
, x
, y
,
8787 lookup_rgb_color (f
,
8788 color_scale
* pixel
.red
,
8789 color_scale
* pixel
.green
,
8790 color_scale
* pixel
.blue
));
8793 DestroyPixelIterator (iterator
);
8796 #ifdef COLOR_TABLE_SUPPORT
8797 /* Remember colors allocated for this image. */
8798 img
->colors
= colors_in_color_table (&img
->ncolors
);
8799 free_color_table ();
8800 #endif /* COLOR_TABLE_SUPPORT */
8803 img
->height
= height
;
8805 /* Put ximg into the image. */
8806 image_put_x_image (f
, img
, ximg
, 0);
8808 /* Final cleanup. image_wand should be the only resource left. */
8809 DestroyMagickWand (image_wand
);
8810 if (bg_wand
) DestroyPixelWand (bg_wand
);
8812 /* `MagickWandTerminus' terminates the imagemagick environment. */
8813 MagickWandTerminus ();
8818 DestroyMagickWand (image_wand
);
8819 if (bg_wand
) DestroyPixelWand (bg_wand
);
8821 MagickWandTerminus ();
8822 /* TODO more cleanup. */
8823 image_error ("Error parsing IMAGEMAGICK image `%s'", img
->spec
);
8828 /* Load IMAGEMAGICK image IMG for use on frame F. Value is true if
8829 successful. this function will go into the imagemagick_type structure, and
8830 the prototype thus needs to be compatible with that structure. */
8833 imagemagick_load (struct frame
*f
, struct image
*img
)
8836 Lisp_Object file_name
;
8838 /* If IMG->spec specifies a file name, create a non-file spec from it. */
8839 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
8840 if (STRINGP (file_name
))
8842 Lisp_Object file
= x_find_image_file (file_name
);
8843 if (!STRINGP (file
))
8845 image_error ("Cannot find image file `%s'", file_name
);
8848 file
= ENCODE_FILE (file
);
8850 file
= ansi_encode_filename (file
);
8852 success_p
= imagemagick_load_image (f
, img
, 0, 0, SSDATA (file
));
8854 /* Else its not a file, its a lisp object. Load the image from a
8855 lisp object rather than a file. */
8860 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
8861 if (!STRINGP (data
))
8863 image_error ("Invalid image data `%s'", data
);
8866 success_p
= imagemagick_load_image (f
, img
, SDATA (data
),
8867 SBYTES (data
), NULL
);
8873 DEFUN ("imagemagick-types", Fimagemagick_types
, Simagemagick_types
, 0, 0, 0,
8874 doc
: /* Return a list of image types supported by ImageMagick.
8875 Each entry in this list is a symbol named after an ImageMagick format
8876 tag. See the ImageMagick manual for a list of ImageMagick formats and
8877 their descriptions (http://www.imagemagick.org/script/formats.php).
8878 You can also try the shell command: `identify -list format'.
8880 Note that ImageMagick recognizes many file-types that Emacs does not
8881 recognize as images, such as C. See `imagemagick-types-enable'
8882 and `imagemagick-types-inhibit'. */)
8885 Lisp_Object typelist
= Qnil
;
8891 GetExceptionInfo(&ex
);
8892 imtypes
= GetMagickList ("*", &numf
, &ex
);
8893 DestroyExceptionInfo(&ex
);
8895 for (i
= 0; i
< numf
; i
++)
8897 Lisp_Object imagemagicktype
= intern (imtypes
[i
]);
8898 typelist
= Fcons (imagemagicktype
, typelist
);
8899 imtypes
[i
] = MagickRelinquishMemory (imtypes
[i
]);
8902 MagickRelinquishMemory (imtypes
);
8903 return Fnreverse (typelist
);
8906 #endif /* defined (HAVE_IMAGEMAGICK) */
8910 /***********************************************************************
8912 ***********************************************************************/
8916 /* Function prototypes. */
8918 static bool svg_image_p (Lisp_Object object
);
8919 static bool svg_load (struct frame
*f
, struct image
*img
);
8921 static bool svg_load_image (struct frame
*, struct image
*,
8922 unsigned char *, ptrdiff_t, char *);
8924 /* Indices of image specification fields in svg_format, below. */
8926 enum svg_keyword_index
8941 /* Vector of image_keyword structures describing the format
8942 of valid user-defined image specifications. */
8944 static const struct image_keyword svg_format
[SVG_LAST
] =
8946 {":type", IMAGE_SYMBOL_VALUE
, 1},
8947 {":data", IMAGE_STRING_VALUE
, 0},
8948 {":file", IMAGE_STRING_VALUE
, 0},
8949 {":ascent", IMAGE_ASCENT_VALUE
, 0},
8950 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
8951 {":relief", IMAGE_INTEGER_VALUE
, 0},
8952 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8953 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8954 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
8955 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
8958 # if defined HAVE_NTGUI && defined WINDOWSNT
8959 static bool init_svg_functions (void);
8961 #define init_svg_functions NULL
8964 /* Structure describing the image type `svg'. Its the same type of
8965 structure defined for all image formats, handled by emacs image
8966 functions. See struct image_type in dispextern.h. */
8968 static struct image_type svg_type
=
8970 SYMBOL_INDEX (Qsvg
),
8979 /* Return true if OBJECT is a valid SVG image specification. Do
8980 this by calling parse_image_spec and supplying the keywords that
8981 identify the SVG format. */
8984 svg_image_p (Lisp_Object object
)
8986 struct image_keyword fmt
[SVG_LAST
];
8987 memcpy (fmt
, svg_format
, sizeof fmt
);
8989 if (!parse_image_spec (object
, fmt
, SVG_LAST
, Qsvg
))
8992 /* Must specify either the :data or :file keyword. */
8993 return fmt
[SVG_FILE
].count
+ fmt
[SVG_DATA
].count
== 1;
8996 # include <librsvg/rsvg.h>
9000 /* SVG library functions. */
9001 DEF_DLL_FN (RsvgHandle
*, rsvg_handle_new
, (void));
9002 DEF_DLL_FN (void, rsvg_handle_get_dimensions
,
9003 (RsvgHandle
*, RsvgDimensionData
*));
9004 DEF_DLL_FN (gboolean
, rsvg_handle_write
,
9005 (RsvgHandle
*, const guchar
*, gsize
, GError
**));
9006 DEF_DLL_FN (gboolean
, rsvg_handle_close
, (RsvgHandle
*, GError
**));
9007 DEF_DLL_FN (GdkPixbuf
*, rsvg_handle_get_pixbuf
, (RsvgHandle
*));
9008 DEF_DLL_FN (void, rsvg_handle_set_base_uri
, (RsvgHandle
*, const char *));
9010 DEF_DLL_FN (int, gdk_pixbuf_get_width
, (const GdkPixbuf
*));
9011 DEF_DLL_FN (int, gdk_pixbuf_get_height
, (const GdkPixbuf
*));
9012 DEF_DLL_FN (guchar
*, gdk_pixbuf_get_pixels
, (const GdkPixbuf
*));
9013 DEF_DLL_FN (int, gdk_pixbuf_get_rowstride
, (const GdkPixbuf
*));
9014 DEF_DLL_FN (GdkColorspace
, gdk_pixbuf_get_colorspace
, (const GdkPixbuf
*));
9015 DEF_DLL_FN (int, gdk_pixbuf_get_n_channels
, (const GdkPixbuf
*));
9016 DEF_DLL_FN (gboolean
, gdk_pixbuf_get_has_alpha
, (const GdkPixbuf
*));
9017 DEF_DLL_FN (int, gdk_pixbuf_get_bits_per_sample
, (const GdkPixbuf
*));
9019 # if ! GLIB_CHECK_VERSION (2, 36, 0)
9020 DEF_DLL_FN (void, g_type_init
, (void));
9022 DEF_DLL_FN (void, g_object_unref
, (gpointer
));
9023 DEF_DLL_FN (void, g_clear_error
, (GError
**));
9026 init_svg_functions (void)
9028 HMODULE library
, gdklib
= NULL
, glib
= NULL
, gobject
= NULL
;
9030 if (!(glib
= w32_delayed_load (Qglib
))
9031 || !(gobject
= w32_delayed_load (Qgobject
))
9032 || !(gdklib
= w32_delayed_load (Qgdk_pixbuf
))
9033 || !(library
= w32_delayed_load (Qsvg
)))
9035 if (gdklib
) FreeLibrary (gdklib
);
9036 if (gobject
) FreeLibrary (gobject
);
9037 if (glib
) FreeLibrary (glib
);
9041 LOAD_DLL_FN (library
, rsvg_handle_new
);
9042 LOAD_DLL_FN (library
, rsvg_handle_get_dimensions
);
9043 LOAD_DLL_FN (library
, rsvg_handle_write
);
9044 LOAD_DLL_FN (library
, rsvg_handle_close
);
9045 LOAD_DLL_FN (library
, rsvg_handle_get_pixbuf
);
9046 LOAD_DLL_FN (library
, rsvg_handle_set_base_uri
);
9048 LOAD_DLL_FN (gdklib
, gdk_pixbuf_get_width
);
9049 LOAD_DLL_FN (gdklib
, gdk_pixbuf_get_height
);
9050 LOAD_DLL_FN (gdklib
, gdk_pixbuf_get_pixels
);
9051 LOAD_DLL_FN (gdklib
, gdk_pixbuf_get_rowstride
);
9052 LOAD_DLL_FN (gdklib
, gdk_pixbuf_get_colorspace
);
9053 LOAD_DLL_FN (gdklib
, gdk_pixbuf_get_n_channels
);
9054 LOAD_DLL_FN (gdklib
, gdk_pixbuf_get_has_alpha
);
9055 LOAD_DLL_FN (gdklib
, gdk_pixbuf_get_bits_per_sample
);
9057 # if ! GLIB_CHECK_VERSION (2, 36, 0)
9058 LOAD_DLL_FN (gobject
, g_type_init
);
9060 LOAD_DLL_FN (gobject
, g_object_unref
);
9061 LOAD_DLL_FN (glib
, g_clear_error
);
9066 /* The following aliases for library functions allow dynamic loading
9067 to be used on some platforms. */
9069 # undef gdk_pixbuf_get_bits_per_sample
9070 # undef gdk_pixbuf_get_colorspace
9071 # undef gdk_pixbuf_get_has_alpha
9072 # undef gdk_pixbuf_get_height
9073 # undef gdk_pixbuf_get_n_channels
9074 # undef gdk_pixbuf_get_pixels
9075 # undef gdk_pixbuf_get_rowstride
9076 # undef gdk_pixbuf_get_width
9077 # undef g_clear_error
9078 # undef g_object_unref
9080 # undef rsvg_handle_close
9081 # undef rsvg_handle_get_dimensions
9082 # undef rsvg_handle_get_pixbuf
9083 # undef rsvg_handle_new
9084 # undef rsvg_handle_set_base_uri
9085 # undef rsvg_handle_write
9087 # define gdk_pixbuf_get_bits_per_sample fn_gdk_pixbuf_get_bits_per_sample
9088 # define gdk_pixbuf_get_colorspace fn_gdk_pixbuf_get_colorspace
9089 # define gdk_pixbuf_get_has_alpha fn_gdk_pixbuf_get_has_alpha
9090 # define gdk_pixbuf_get_height fn_gdk_pixbuf_get_height
9091 # define gdk_pixbuf_get_n_channels fn_gdk_pixbuf_get_n_channels
9092 # define gdk_pixbuf_get_pixels fn_gdk_pixbuf_get_pixels
9093 # define gdk_pixbuf_get_rowstride fn_gdk_pixbuf_get_rowstride
9094 # define gdk_pixbuf_get_width fn_gdk_pixbuf_get_width
9095 # define g_clear_error fn_g_clear_error
9096 # define g_object_unref fn_g_object_unref
9097 # define g_type_init fn_g_type_init
9098 # define rsvg_handle_close fn_rsvg_handle_close
9099 # define rsvg_handle_get_dimensions fn_rsvg_handle_get_dimensions
9100 # define rsvg_handle_get_pixbuf fn_rsvg_handle_get_pixbuf
9101 # define rsvg_handle_new fn_rsvg_handle_new
9102 # define rsvg_handle_set_base_uri fn_rsvg_handle_set_base_uri
9103 # define rsvg_handle_write fn_rsvg_handle_write
9105 # endif /* !WINDOWSNT */
9107 /* Load SVG image IMG for use on frame F. Value is true if
9111 svg_load (struct frame
*f
, struct image
*img
)
9114 Lisp_Object file_name
;
9116 /* If IMG->spec specifies a file name, create a non-file spec from it. */
9117 file_name
= image_spec_value (img
->spec
, QCfile
, NULL
);
9118 if (STRINGP (file_name
))
9121 Lisp_Object file
= x_find_image_fd (file_name
, &fd
);
9122 if (!STRINGP (file
))
9124 image_error ("Cannot find image file `%s'", file_name
);
9128 /* Read the entire file into memory. */
9130 unsigned char *contents
= slurp_file (fd
, &size
);
9131 if (contents
== NULL
)
9133 image_error ("Error loading SVG image `%s'", file
);
9136 /* If the file was slurped into memory properly, parse it. */
9137 success_p
= svg_load_image (f
, img
, contents
, size
,
9138 SSDATA (ENCODE_FILE (file
)));
9141 /* Else its not a file, its a lisp object. Load the image from a
9142 lisp object rather than a file. */
9145 Lisp_Object data
, original_filename
;
9147 data
= image_spec_value (img
->spec
, QCdata
, NULL
);
9148 if (!STRINGP (data
))
9150 image_error ("Invalid image data `%s'", data
);
9153 original_filename
= BVAR (current_buffer
, filename
);
9154 success_p
= svg_load_image (f
, img
, SDATA (data
), SBYTES (data
),
9155 (NILP (original_filename
) ? NULL
9156 : SSDATA (original_filename
)));
9162 /* svg_load_image is a helper function for svg_load, which does the
9163 actual loading given contents and size, apart from frame and image
9164 structures, passed from svg_load.
9166 Uses librsvg to do most of the image processing.
9168 Returns true when successful. */
9170 svg_load_image (struct frame
*f
, /* Pointer to emacs frame structure. */
9171 struct image
*img
, /* Pointer to emacs image structure. */
9172 unsigned char *contents
, /* String containing the SVG XML data to be parsed. */
9173 ptrdiff_t size
, /* Size of data in bytes. */
9174 char *filename
) /* Name of SVG file being loaded. */
9176 RsvgHandle
*rsvg_handle
;
9177 RsvgDimensionData dimension_data
;
9182 const guint8
*pixels
;
9185 #if ! GLIB_CHECK_VERSION (2, 36, 0)
9186 /* g_type_init is a glib function that must be called prior to
9187 using gnome type library functions (obsolete since 2.36.0). */
9191 /* Make a handle to a new rsvg object. */
9192 rsvg_handle
= rsvg_handle_new ();
9194 /* Set base_uri for properly handling referenced images (via 'href').
9195 See rsvg bug 596114 - "image refs are relative to curdir, not .svg file"
9196 (https://bugzilla.gnome.org/show_bug.cgi?id=596114). */
9198 rsvg_handle_set_base_uri(rsvg_handle
, filename
);
9200 /* Parse the contents argument and fill in the rsvg_handle. */
9201 rsvg_handle_write (rsvg_handle
, contents
, size
, &err
);
9202 if (err
) goto rsvg_error
;
9204 /* The parsing is complete, rsvg_handle is ready to used, close it
9205 for further writes. */
9206 rsvg_handle_close (rsvg_handle
, &err
);
9207 if (err
) goto rsvg_error
;
9209 rsvg_handle_get_dimensions (rsvg_handle
, &dimension_data
);
9210 if (! check_image_size (f
, dimension_data
.width
, dimension_data
.height
))
9212 image_size_error ();
9216 /* We can now get a valid pixel buffer from the svg file, if all
9218 pixbuf
= rsvg_handle_get_pixbuf (rsvg_handle
);
9219 if (!pixbuf
) goto rsvg_error
;
9220 g_object_unref (rsvg_handle
);
9222 /* Extract some meta data from the svg handle. */
9223 width
= gdk_pixbuf_get_width (pixbuf
);
9224 height
= gdk_pixbuf_get_height (pixbuf
);
9225 pixels
= gdk_pixbuf_get_pixels (pixbuf
);
9226 rowstride
= gdk_pixbuf_get_rowstride (pixbuf
);
9228 /* Validate the svg meta data. */
9229 eassert (gdk_pixbuf_get_colorspace (pixbuf
) == GDK_COLORSPACE_RGB
);
9230 eassert (gdk_pixbuf_get_n_channels (pixbuf
) == 4);
9231 eassert (gdk_pixbuf_get_has_alpha (pixbuf
));
9232 eassert (gdk_pixbuf_get_bits_per_sample (pixbuf
) == 8);
9236 unsigned char *data
= (unsigned char *) xmalloc (width
*height
*4);
9237 uint32_t bgcolor
= get_spec_bg_or_alpha_as_argb (img
, f
);
9239 for (int y
= 0; y
< height
; ++y
)
9241 const guchar
*iconptr
= pixels
+ y
* rowstride
;
9242 uint32_t *dataptr
= (uint32_t *) (data
+ y
* rowstride
);
9244 for (int x
= 0; x
< width
; ++x
)
9246 if (iconptr
[3] == 0)
9249 *dataptr
= (iconptr
[0] << 16)
9252 | (iconptr
[3] << 24);
9259 create_cairo_image_surface (img
, data
, width
, height
);
9260 g_object_unref (pixbuf
);
9263 /* Try to create a x pixmap to hold the svg pixmap. */
9265 if (!image_create_x_image_and_pixmap (f
, img
, width
, height
, 0, &ximg
, 0))
9267 g_object_unref (pixbuf
);
9271 init_color_table ();
9273 /* Handle alpha channel by combining the image with a background
9276 Lisp_Object specified_bg
= image_spec_value (img
->spec
, QCbackground
, NULL
);
9277 if (!STRINGP (specified_bg
)
9278 || !x_defined_color (f
, SSDATA (specified_bg
), &background
, 0))
9279 x_query_frame_background_color (f
, &background
);
9281 /* SVG pixmaps specify transparency in the last byte, so right
9282 shift 8 bits to get rid of it, since emacs doesn't support
9284 background
.red
>>= 8;
9285 background
.green
>>= 8;
9286 background
.blue
>>= 8;
9288 /* This loop handles opacity values, since Emacs assumes
9289 non-transparent images. Each pixel must be "flattened" by
9290 calculating the resulting color, given the transparency of the
9291 pixel, and the image background color. */
9292 for (int y
= 0; y
< height
; ++y
)
9294 for (int x
= 0; x
< width
; ++x
)
9304 opacity
= *pixels
++;
9306 red
= ((red
* opacity
)
9307 + (background
.red
* ((1 << 8) - opacity
)));
9308 green
= ((green
* opacity
)
9309 + (background
.green
* ((1 << 8) - opacity
)));
9310 blue
= ((blue
* opacity
)
9311 + (background
.blue
* ((1 << 8) - opacity
)));
9313 XPutPixel (ximg
, x
, y
, lookup_rgb_color (f
, red
, green
, blue
));
9316 pixels
+= rowstride
- 4 * width
;
9319 #ifdef COLOR_TABLE_SUPPORT
9320 /* Remember colors allocated for this image. */
9321 img
->colors
= colors_in_color_table (&img
->ncolors
);
9322 free_color_table ();
9323 #endif /* COLOR_TABLE_SUPPORT */
9325 g_object_unref (pixbuf
);
9328 img
->height
= height
;
9330 /* Maybe fill in the background field while we have ximg handy.
9331 Casting avoids a GCC warning. */
9332 IMAGE_BACKGROUND (img
, f
, (XImagePtr_or_DC
)ximg
);
9334 /* Put ximg into the image. */
9335 image_put_x_image (f
, img
, ximg
, 0);
9336 #endif /* ! USE_CAIRO */
9341 g_object_unref (rsvg_handle
);
9342 /* FIXME: Use error->message so the user knows what is the actual
9343 problem with the image. */
9344 image_error ("Error parsing SVG image `%s'", img
->spec
);
9345 g_clear_error (&err
);
9349 #endif /* defined (HAVE_RSVG) */
9354 /***********************************************************************
9356 ***********************************************************************/
9358 #ifdef HAVE_X_WINDOWS
9359 #define HAVE_GHOSTSCRIPT 1
9360 #endif /* HAVE_X_WINDOWS */
9362 #ifdef HAVE_GHOSTSCRIPT
9364 static bool gs_image_p (Lisp_Object object
);
9365 static bool gs_load (struct frame
*f
, struct image
*img
);
9366 static void gs_clear_image (struct frame
*f
, struct image
*img
);
9368 /* Indices of image specification fields in gs_format, below. */
9370 enum gs_keyword_index
9388 /* Vector of image_keyword structures describing the format
9389 of valid user-defined image specifications. */
9391 static const struct image_keyword gs_format
[GS_LAST
] =
9393 {":type", IMAGE_SYMBOL_VALUE
, 1},
9394 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9395 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE
, 1},
9396 {":file", IMAGE_STRING_VALUE
, 1},
9397 {":loader", IMAGE_FUNCTION_VALUE
, 0},
9398 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE
, 1},
9399 {":ascent", IMAGE_ASCENT_VALUE
, 0},
9400 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR
, 0},
9401 {":relief", IMAGE_INTEGER_VALUE
, 0},
9402 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9403 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9404 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE
, 0},
9405 {":background", IMAGE_STRING_OR_NIL_VALUE
, 0}
9408 /* Structure describing the image type `ghostscript'. */
9410 static struct image_type gs_type
=
9412 SYMBOL_INDEX (Qpostscript
),
9421 /* Free X resources of Ghostscript image IMG which is used on frame F. */
9424 gs_clear_image (struct frame
*f
, struct image
*img
)
9426 x_clear_image (f
, img
);
9430 /* Return true if OBJECT is a valid Ghostscript image
9434 gs_image_p (Lisp_Object object
)
9436 struct image_keyword fmt
[GS_LAST
];
9440 memcpy (fmt
, gs_format
, sizeof fmt
);
9442 if (!parse_image_spec (object
, fmt
, GS_LAST
, Qpostscript
))
9445 /* Bounding box must be a list or vector containing 4 integers. */
9446 tem
= fmt
[GS_BOUNDING_BOX
].value
;
9449 for (i
= 0; i
< 4; ++i
, tem
= XCDR (tem
))
9450 if (!CONSP (tem
) || !INTEGERP (XCAR (tem
)))
9455 else if (VECTORP (tem
))
9457 if (ASIZE (tem
) != 4)
9459 for (i
= 0; i
< 4; ++i
)
9460 if (!INTEGERP (AREF (tem
, i
)))
9470 /* Load Ghostscript image IMG for use on frame F. Value is true
9474 gs_load (struct frame
*f
, struct image
*img
)
9476 uprintmax_t printnum1
, printnum2
;
9477 char buffer
[sizeof " " + INT_STRLEN_BOUND (printmax_t
)];
9478 Lisp_Object window_and_pixmap_id
= Qnil
, loader
, pt_height
, pt_width
;
9480 double in_width
, in_height
;
9481 Lisp_Object pixel_colors
= Qnil
;
9483 /* Compute pixel size of pixmap needed from the given size in the
9484 image specification. Sizes in the specification are in pt. 1 pt
9485 = 1/72 in, xdpi and ydpi are stored in the frame's X display
9487 pt_width
= image_spec_value (img
->spec
, QCpt_width
, NULL
);
9488 in_width
= INTEGERP (pt_width
) ? XFASTINT (pt_width
) / 72.0 : 0;
9489 in_width
*= FRAME_RES_X (f
);
9490 pt_height
= image_spec_value (img
->spec
, QCpt_height
, NULL
);
9491 in_height
= INTEGERP (pt_height
) ? XFASTINT (pt_height
) / 72.0 : 0;
9492 in_height
*= FRAME_RES_Y (f
);
9494 if (! (in_width
<= INT_MAX
&& in_height
<= INT_MAX
9495 && check_image_size (f
, in_width
, in_height
)))
9497 image_size_error ();
9500 img
->width
= in_width
;
9501 img
->height
= in_height
;
9503 /* Create the pixmap. */
9504 eassert (img
->pixmap
== NO_PIXMAP
);
9506 if (x_check_image_size (0, img
->width
, img
->height
))
9508 /* Only W32 version did BLOCK_INPUT here. ++kfs */
9510 img
->pixmap
= XCreatePixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9511 img
->width
, img
->height
,
9512 DefaultDepthOfScreen (FRAME_X_SCREEN (f
)));
9518 image_error ("Unable to create pixmap for `%s'" , img
->spec
);
9522 /* Call the loader to fill the pixmap. It returns a process object
9523 if successful. We do not record_unwind_protect here because
9524 other places in redisplay like calling window scroll functions
9525 don't either. Let the Lisp loader use `unwind-protect' instead. */
9526 printnum1
= FRAME_X_WINDOW (f
);
9527 printnum2
= img
->pixmap
;
9528 window_and_pixmap_id
9529 = make_formatted_string (buffer
, "%"pMu
" %"pMu
, printnum1
, printnum2
);
9531 printnum1
= FRAME_FOREGROUND_PIXEL (f
);
9532 printnum2
= FRAME_BACKGROUND_PIXEL (f
);
9534 = make_formatted_string (buffer
, "%"pMu
" %"pMu
, printnum1
, printnum2
);
9536 XSETFRAME (frame
, f
);
9537 loader
= image_spec_value (img
->spec
, QCloader
, NULL
);
9539 loader
= intern ("gs-load-image");
9541 img
->lisp_data
= call6 (loader
, frame
, img
->spec
,
9542 make_number (img
->width
),
9543 make_number (img
->height
),
9544 window_and_pixmap_id
,
9546 return PROCESSP (img
->lisp_data
);
9550 /* Kill the Ghostscript process that was started to fill PIXMAP on
9551 frame F. Called from XTread_socket when receiving an event
9552 telling Emacs that Ghostscript has finished drawing. */
9555 x_kill_gs_process (Pixmap pixmap
, struct frame
*f
)
9557 struct image_cache
*c
= FRAME_IMAGE_CACHE (f
);
9561 /* Find the image containing PIXMAP. */
9562 for (i
= 0; i
< c
->used
; ++i
)
9563 if (c
->images
[i
]->pixmap
== pixmap
)
9566 /* Should someone in between have cleared the image cache, for
9567 instance, give up. */
9571 /* Kill the GS process. We should have found PIXMAP in the image
9572 cache and its image should contain a process object. */
9574 eassert (PROCESSP (img
->lisp_data
));
9575 Fkill_process (img
->lisp_data
, Qnil
);
9576 img
->lisp_data
= Qnil
;
9578 #if defined (HAVE_X_WINDOWS)
9580 /* On displays with a mutable colormap, figure out the colors
9581 allocated for the image by looking at the pixels of an XImage for
9583 if (x_mutable_colormap (FRAME_X_VISUAL (f
)))
9589 /* Try to get an XImage for img->pixmep. */
9590 ximg
= XGetImage (FRAME_X_DISPLAY (f
), img
->pixmap
,
9591 0, 0, img
->width
, img
->height
, ~0, ZPixmap
);
9594 /* Initialize the color table. */
9595 init_color_table ();
9597 /* For each pixel of the image, look its color up in the
9598 color table. After having done so, the color table will
9599 contain an entry for each color used by the image. */
9600 #ifdef COLOR_TABLE_SUPPORT
9601 for (int y
= 0; y
< img
->height
; ++y
)
9602 for (int x
= 0; x
< img
->width
; ++x
)
9604 unsigned long pixel
= XGetPixel (ximg
, x
, y
);
9606 lookup_pixel_color (f
, pixel
);
9609 /* Record colors in the image. Free color table and XImage. */
9610 img
->colors
= colors_in_color_table (&img
->ncolors
);
9611 free_color_table ();
9613 XDestroyImage (ximg
);
9615 #if 0 /* This doesn't seem to be the case. If we free the colors
9616 here, we get a BadAccess later in x_clear_image when
9617 freeing the colors. */
9618 /* We have allocated colors once, but Ghostscript has also
9619 allocated colors on behalf of us. So, to get the
9620 reference counts right, free them once. */
9622 x_free_colors (f
, img
->colors
, img
->ncolors
);
9626 image_error ("Cannot get X image of `%s'; colors will not be freed",
9631 #endif /* HAVE_X_WINDOWS */
9633 /* Now that we have the pixmap, compute mask and transform the
9634 image if requested. */
9636 postprocess_image (f
, img
);
9640 #endif /* HAVE_GHOSTSCRIPT */
9643 /***********************************************************************
9645 ***********************************************************************/
9649 DEFUN ("imagep", Fimagep
, Simagep
, 1, 1, 0,
9650 doc
: /* Value is non-nil if SPEC is a valid image specification. */)
9653 return valid_image_p (spec
) ? Qt
: Qnil
;
9657 DEFUN ("lookup-image", Flookup_image
, Slookup_image
, 1, 1, 0,
9663 if (valid_image_p (spec
))
9664 id
= lookup_image (SELECTED_FRAME (), spec
);
9667 return make_number (id
);
9670 #endif /* GLYPH_DEBUG */
9673 /***********************************************************************
9675 ***********************************************************************/
9677 DEFUN ("init-image-library", Finit_image_library
, Sinit_image_library
, 1, 1, 0,
9678 doc
: /* Initialize image library implementing image type TYPE.
9679 Return non-nil if TYPE is a supported image type.
9681 If image libraries are loaded dynamically (currently only the case on
9682 MS-Windows), load the library for TYPE if it is not yet loaded, using
9683 the library file(s) specified by `dynamic-library-alist'. */)
9686 return lookup_image_type (type
) ? Qt
: Qnil
;
9689 /* Look up image type TYPE, and return a pointer to its image_type
9690 structure. Return 0 if TYPE is not a known image type. */
9692 static struct image_type
*
9693 lookup_image_type (Lisp_Object type
)
9695 /* Types pbm and xbm are built-in and always available. */
9696 if (EQ (type
, Qpbm
))
9697 return define_image_type (&pbm_type
);
9699 if (EQ (type
, Qxbm
))
9700 return define_image_type (&xbm_type
);
9702 #if defined (HAVE_XPM) || defined (HAVE_NS)
9703 if (EQ (type
, Qxpm
))
9704 return define_image_type (&xpm_type
);
9707 #if defined (HAVE_JPEG) || defined (HAVE_NS)
9708 if (EQ (type
, Qjpeg
))
9709 return define_image_type (&jpeg_type
);
9712 #if defined (HAVE_TIFF) || defined (HAVE_NS)
9713 if (EQ (type
, Qtiff
))
9714 return define_image_type (&tiff_type
);
9717 #if defined (HAVE_GIF) || defined (HAVE_NS)
9718 if (EQ (type
, Qgif
))
9719 return define_image_type (&gif_type
);
9722 #if defined (HAVE_PNG) || defined (HAVE_NS) || defined (USE_CAIRO)
9723 if (EQ (type
, Qpng
))
9724 return define_image_type (&png_type
);
9727 #if defined (HAVE_RSVG)
9728 if (EQ (type
, Qsvg
))
9729 return define_image_type (&svg_type
);
9732 #if defined (HAVE_IMAGEMAGICK)
9733 if (EQ (type
, Qimagemagick
))
9734 return define_image_type (&imagemagick_type
);
9737 #ifdef HAVE_GHOSTSCRIPT
9738 if (EQ (type
, Qpostscript
))
9739 return define_image_type (&gs_type
);
9745 /* Reset image_types before dumping.
9746 Called from Fdump_emacs. */
9749 reset_image_types (void)
9753 struct image_type
*next
= image_types
->next
;
9754 xfree (image_types
);
9760 syms_of_image (void)
9762 /* Initialize this only once; it will be reset before dumping. */
9765 /* Must be defined now because we're going to update it below, while
9766 defining the supported image types. */
9767 DEFVAR_LISP ("image-types", Vimage_types
,
9768 doc
: /* List of potentially supported image types.
9769 Each element of the list is a symbol for an image type, like `jpeg' or `png'.
9770 To check whether it is really supported, use `image-type-available-p'. */);
9771 Vimage_types
= Qnil
;
9773 DEFVAR_LISP ("max-image-size", Vmax_image_size
,
9774 doc
: /* Maximum size of images.
9775 Emacs will not load an image into memory if its pixel width or
9776 pixel height exceeds this limit.
9778 If the value is an integer, it directly specifies the maximum
9779 image height and width, measured in pixels. If it is a floating
9780 point number, it specifies the maximum image height and width
9781 as a ratio to the frame height and width. If the value is
9782 non-numeric, there is no explicit limit on the size of images. */);
9783 Vmax_image_size
= make_float (MAX_IMAGE_SIZE
);
9785 /* Other symbols. */
9786 DEFSYM (Qcount
, "count");
9787 DEFSYM (Qextension_data
, "extension-data");
9788 DEFSYM (Qdelay
, "delay");
9791 DEFSYM (QCascent
, ":ascent");
9792 DEFSYM (QCmargin
, ":margin");
9793 DEFSYM (QCrelief
, ":relief");
9794 DEFSYM (QCconversion
, ":conversion");
9795 DEFSYM (QCcolor_symbols
, ":color-symbols");
9796 DEFSYM (QCheuristic_mask
, ":heuristic-mask");
9797 DEFSYM (QCindex
, ":index");
9798 DEFSYM (QCcrop
, ":crop");
9799 DEFSYM (QCrotation
, ":rotation");
9800 DEFSYM (QCmatrix
, ":matrix");
9801 DEFSYM (QCcolor_adjustment
, ":color-adjustment");
9802 DEFSYM (QCmask
, ":mask");
9804 /* Other symbols. */
9805 DEFSYM (Qlaplace
, "laplace");
9806 DEFSYM (Qemboss
, "emboss");
9807 DEFSYM (Qedge_detection
, "edge-detection");
9808 DEFSYM (Qheuristic
, "heuristic");
9810 DEFSYM (Qpostscript
, "postscript");
9811 DEFSYM (QCmax_width
, ":max-width");
9812 DEFSYM (QCmax_height
, ":max-height");
9813 #ifdef HAVE_GHOSTSCRIPT
9814 ADD_IMAGE_TYPE (Qpostscript
);
9815 DEFSYM (QCloader
, ":loader");
9816 DEFSYM (QCpt_width
, ":pt-width");
9817 DEFSYM (QCpt_height
, ":pt-height");
9818 #endif /* HAVE_GHOSTSCRIPT */
9821 /* Versions of libpng, libgif, and libjpeg that we were compiled with,
9822 or -1 if no PNG/GIF support was compiled in. This is tested by
9823 w32-win.el to correctly set up the alist used to search for the
9824 respective image libraries. */
9825 DEFSYM (Qlibpng_version
, "libpng-version");
9826 Fset (Qlibpng_version
,
9828 make_number (PNG_LIBPNG_VER
)
9833 DEFSYM (Qlibgif_version
, "libgif-version");
9834 Fset (Qlibgif_version
,
9836 make_number (GIFLIB_MAJOR
* 10000
9837 + GIFLIB_MINOR
* 100
9843 DEFSYM (Qlibjpeg_version
, "libjpeg-version");
9844 Fset (Qlibjpeg_version
,
9846 make_number (JPEG_LIB_VERSION
)
9853 DEFSYM (Qpbm
, "pbm");
9854 ADD_IMAGE_TYPE (Qpbm
);
9856 DEFSYM (Qxbm
, "xbm");
9857 ADD_IMAGE_TYPE (Qxbm
);
9859 #if defined (HAVE_XPM) || defined (HAVE_NS)
9860 DEFSYM (Qxpm
, "xpm");
9861 ADD_IMAGE_TYPE (Qxpm
);
9864 #if defined (HAVE_JPEG) || defined (HAVE_NS)
9865 DEFSYM (Qjpeg
, "jpeg");
9866 ADD_IMAGE_TYPE (Qjpeg
);
9869 #if defined (HAVE_TIFF) || defined (HAVE_NS)
9870 DEFSYM (Qtiff
, "tiff");
9871 ADD_IMAGE_TYPE (Qtiff
);
9874 #if defined (HAVE_GIF) || defined (HAVE_NS)
9875 DEFSYM (Qgif
, "gif");
9876 ADD_IMAGE_TYPE (Qgif
);
9879 #if defined (HAVE_PNG) || defined (HAVE_NS)
9880 DEFSYM (Qpng
, "png");
9881 ADD_IMAGE_TYPE (Qpng
);
9884 #if defined (HAVE_IMAGEMAGICK)
9885 DEFSYM (Qimagemagick
, "imagemagick");
9886 ADD_IMAGE_TYPE (Qimagemagick
);
9889 #if defined (HAVE_RSVG)
9890 DEFSYM (Qsvg
, "svg");
9891 ADD_IMAGE_TYPE (Qsvg
);
9893 /* Other libraries used directly by svg code. */
9894 DEFSYM (Qgdk_pixbuf
, "gdk-pixbuf");
9895 DEFSYM (Qglib
, "glib");
9896 DEFSYM (Qgobject
, "gobject");
9897 #endif /* HAVE_NTGUI */
9898 #endif /* HAVE_RSVG */
9900 defsubr (&Sinit_image_library
);
9901 #ifdef HAVE_IMAGEMAGICK
9902 defsubr (&Simagemagick_types
);
9904 defsubr (&Sclear_image_cache
);
9905 defsubr (&Simage_flush
);
9906 defsubr (&Simage_size
);
9907 defsubr (&Simage_mask_p
);
9908 defsubr (&Simage_metadata
);
9912 defsubr (&Slookup_image
);
9915 DEFVAR_BOOL ("cross-disabled-images", cross_disabled_images
,
9916 doc
: /* Non-nil means always draw a cross over disabled images.
9917 Disabled images are those having a `:conversion disabled' property.
9918 A cross is always drawn on black & white displays. */);
9919 cross_disabled_images
= 0;
9921 DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path
,
9922 doc
: /* List of directories to search for window system bitmap files. */);
9923 Vx_bitmap_file_path
= decode_env_path (0, PATH_BITMAPS
, 0);
9925 DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay
,
9926 doc
: /* Maximum time after which images are removed from the cache.
9927 When an image has not been displayed this many seconds, Emacs
9928 automatically removes it from the image cache. If the cache contains
9929 a large number of images, the actual eviction time may be shorter.
9930 The value can also be nil, meaning the cache is never cleared.
9932 The function `clear-image-cache' disregards this variable. */);
9933 Vimage_cache_eviction_delay
= make_number (300);
9934 #ifdef HAVE_IMAGEMAGICK
9935 DEFVAR_INT ("imagemagick-render-type", imagemagick_render_type
,
9936 doc
: /* Integer indicating which ImageMagick rendering method to use.
9938 0 -- the default method (pixel pushing)
9939 1 -- a newer method ("MagickExportImagePixels") that may perform
9940 better (speed etc) in some cases, but has not been as thoroughly
9941 tested with Emacs as the default method. This method requires
9942 ImageMagick version 6.4.6 (approximately) or later.
9944 /* MagickExportImagePixels is in 6.4.6-9, but not 6.4.4-10. */
9945 imagemagick_render_type
= 0;