a | at | ath | athe | athen | athena ) val=athena ;;
m | mo | mot | moti | motif ) val=motif ;;
g | gt | gtk ) val=gtk ;;
+ gtk3 ) val=gtk3 ;;
* )
-as_fn_error $? "\`--with-x-toolkit=$withval' is invalid;
+as_fn_error "\`--with-x-toolkit=$withval' is invalid;
- this option's value should be \`yes', \`no', \`lucid', \`athena', \`motif' or \`gtk'.
- \`yes' and \`gtk' are synonyms. \`athena' and \`lucid' are synonyms." "$LINENO" 5
+ this option's value should be \`yes', \`no', \`lucid', \`athena', \`motif', \`gtk' or
+ \`gtk3'. \`yes' and \`gtk' are synonyms. \`athena' and \`lucid' are synonyms." "$LINENO" 5
;;
esac
with_x_toolkit=$val
fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+ $as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+ if test "${ac_cv_c_bigendian+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+ else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ #ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ #include <sys/types.h>
+ #include <sys/param.h>
+
+ int
+ main ()
+ {
+ #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+ }
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ #include <sys/types.h>
+ #include <sys/param.h>
+
+ int
+ main ()
+ {
+ #if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+ }
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+ else
+ ac_cv_c_bigendian=no
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ #include <limits.h>
+
+ int
+ main ()
+ {
+ #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+ }
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ #include <limits.h>
+
+ int
+ main ()
+ {
+ #ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+ }
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+ else
+ ac_cv_c_bigendian=no
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+ int
+ main ()
+ {
+ return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+ }
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ $ac_includes_default
+ int
+ main ()
+ {
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+ }
+ _ACEOF
+ if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_bigendian=no
+ else
+ ac_cv_c_bigendian=yes
+ fi
+ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+ fi
+
+ fi
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+ $as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+ ;; #(
+ no)
+ ;; #(
+ universal)
+
+ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
- as_fn_error $? "unknown endianness
+ ;; #(
+ *)
++ as_fn_error "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
HAVE_GTK=no
- as_fn_error $? "$GTK_PKG_ERRORS" "$LINENO" 5
+ if test "${with_gtk3}" = "yes"; then
+ GLIB_REQUIRED=2.6
+ GTK_REQUIRED=2.90
+ GTK_MODULES="gtk+-3.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED"
+
+
+ succeeded=no
+
+ # Extract the first word of "pkg-config", so it can be a program name with args.
+ set dummy pkg-config; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+ $as_echo_n "checking for $ac_word... " >&6; }
+ if test "${ac_cv_path_PKG_CONFIG+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+ else
+ case $PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ for as_dir in $PATH
+ do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+ done
+ done
+ IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
+ ;;
+ esac
+ fi
+ PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+ if test -n "$PKG_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+ $as_echo "$PKG_CONFIG" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ $as_echo "no" >&6; }
+ fi
+
+
+
+ if test "$PKG_CONFIG" = "no" ; then
+ pkg_check_gtk=no
+ else
+ PKG_CONFIG_MIN_VERSION=0.9.0
+ if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $GTK_MODULES" >&5
+ $as_echo_n "checking for $GTK_MODULES... " >&6; }
+
+ if $PKG_CONFIG --exists "$GTK_MODULES" 2>&5; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+ $as_echo "yes" >&6; }
+ succeeded=yes
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking GTK_CFLAGS" >&5
+ $as_echo_n "checking GTK_CFLAGS... " >&6; }
+ GTK_CFLAGS=`$PKG_CONFIG --cflags "$GTK_MODULES"|sed -e 's,///*,/,g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTK_CFLAGS" >&5
+ $as_echo "$GTK_CFLAGS" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking GTK_LIBS" >&5
+ $as_echo_n "checking GTK_LIBS... " >&6; }
+ GTK_LIBS=`$PKG_CONFIG --libs "$GTK_MODULES"|sed -e 's,///*,/,g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTK_LIBS" >&5
+ $as_echo "$GTK_LIBS" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ $as_echo "no" >&6; }
+ GTK_CFLAGS=""
+ GTK_LIBS=""
+ ## If we have a custom action on failure, don't print errors, but
+ ## do set a variable so people can do so.
+ GTK_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$GTK_MODULES"`
+
+ fi
+
+
+
+ else
+ echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
+ echo "*** See http://www.freedesktop.org/software/pkgconfig"
+ fi
+ fi
+
+ if test $succeeded = yes; then
+ pkg_check_gtk=yes
+ else
+ pkg_check_gtk=no
+ fi
+
+ if test "$pkg_check_gtk" = "no" && test "$USE_X_TOOLKIT" != "maybe"; then
++ as_fn_error "$GTK_PKG_ERRORS" "$LINENO" 5
+ fi
+ fi
+
+ if test "$pkg_check_gtk" != "yes"; then
+ HAVE_GTK=no
if test "${with_gtk}" = "yes" || test "$USE_X_TOOLKIT" = "maybe"; then
GLIB_REQUIRED=2.6
GTK_REQUIRED=2.6
fi
if test "$pkg_check_gtk" = "no" && test "$USE_X_TOOLKIT" != "maybe"; then
- as_fn_error $? "$GTK_PKG_ERRORS" "$LINENO" 5
+ as_fn_error "$GTK_PKG_ERRORS" "$LINENO" 5
fi
fi
-
+ fi
GTK_OBJ=
if test x"$pkg_check_gtk" = xyes; then
$as_echo "#define HAVE_GTK_AND_PTHREAD 1" >>confdefs.h
fi
- fi
+
+ for ac_func in gtk_widget_get_window gtk_widget_set_has_window \
+ gtk_dialog_get_action_area gtk_widget_get_sensitive \
+ gtk_widget_get_mapped gtk_adjustment_get_page_size \
+ gtk_orientable_set_orientation
+ do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
++eval as_val=\$$as_ac_var
++ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+ #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+ _ACEOF
+
+ fi
+ done
+
+
fi
HAVE_DBUS=no
#endif /* HAVE_NTGUI */
#ifdef HAVE_NS
- void *bitmap = ns_image_from_XBM(bits, width, height);
+ void *bitmap = ns_image_from_XBM (bits, width, height);
if (!bitmap)
- return -1;
+ return -1;
#endif
id = x_allocate_bitmap_record (f);
#ifdef HAVE_NS
int id;
- void *bitmap = ns_image_from_file(file);
+ void *bitmap = ns_image_from_file (file);
if (!bitmap)
- return -1;
+ return -1;
id = x_allocate_bitmap_record (f);
/* Keywords. */
- extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile;
- extern Lisp_Object QCdata, QCtype;
- extern Lisp_Object Qcenter;
Lisp_Object QCascent, QCmargin, QCrelief, Qcount, Qextension_data;
Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask;
-Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask;
+Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask, QCgeometry, QCcrop, QCrotation;
/* Other symbols. */
/* Function prototypes. */
- static Lisp_Object define_image_type P_ ((struct image_type *type, int loaded));
- static struct image_type *lookup_image_type P_ ((Lisp_Object symbol));
- static void image_error P_ ((char *format, Lisp_Object, Lisp_Object));
- static void x_laplace P_ ((struct frame *, struct image *));
- static void x_emboss P_ ((struct frame *, struct image *));
- static int x_build_heuristic_mask P_ ((struct frame *, struct image *,
- Lisp_Object));
+ static Lisp_Object define_image_type (struct image_type *type, int loaded);
+ static struct image_type *lookup_image_type (Lisp_Object symbol);
+ static void image_error (const char *format, Lisp_Object, Lisp_Object);
+ static void x_laplace (struct frame *, struct image *);
+ static void x_emboss (struct frame *, struct image *);
+ static int x_build_heuristic_mask (struct frame *, struct image *,
+ Lisp_Object);
-#define CACHE_IMAGE_TYPE(type, status) \
+#define CACHE_IMAGE_TYPE(type, status) \
do { Vimage_type_cache = Fcons (Fcons (type, status), Vimage_type_cache); } while (0)
-#define ADD_IMAGE_TYPE(type) \
+#define ADD_IMAGE_TYPE(type) \
do { Vimage_types = Fcons (type, Vimage_types); } while (0)
/* Define a new image type from TYPE. This adds a copy of TYPE to
\f
/***********************************************************************
Image type independent image structures
- ***********************************************************************/
+***********************************************************************/
- static struct image *make_image P_ ((Lisp_Object spec, unsigned hash));
- static void free_image P_ ((struct frame *f, struct image *img));
- static int check_image_size P_ ((struct frame *f, int width, int height));
+ static struct image *make_image (Lisp_Object spec, unsigned hash);
+ static void free_image (struct frame *f, struct image *img);
+ static int check_image_size (struct frame *f, int width, int height);
#define MAX_IMAGE_SIZE 6.0
Lisp_Object Vmax_image_size;
\f
/***********************************************************************
Helper functions for X image types
- ***********************************************************************/
+***********************************************************************/
- static void x_clear_image_1 P_ ((struct frame *, struct image *, int,
- int, int));
- static void x_clear_image P_ ((struct frame *f, struct image *img));
- static unsigned long x_alloc_image_color P_ ((struct frame *f,
- struct image *img,
- Lisp_Object color_name,
- unsigned long dflt));
+ static void x_clear_image_1 (struct frame *, struct image *, int,
+ int, int);
+ static void x_clear_image (struct frame *f, struct image *img);
+ static unsigned long x_alloc_image_color (struct frame *f,
+ struct image *img,
+ Lisp_Object color_name,
+ unsigned long dflt);
/* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
\f
/***********************************************************************
Image Cache
- ***********************************************************************/
+***********************************************************************/
- static struct image *search_image_cache P_ ((struct frame *, Lisp_Object, unsigned));
- static void cache_image P_ ((struct frame *f, struct image *img));
- static void postprocess_image P_ ((struct frame *, struct image *));
+ static struct image *search_image_cache (struct frame *, Lisp_Object, unsigned);
+ static void cache_image (struct frame *f, struct image *img);
+ static void postprocess_image (struct frame *, struct image *);
/* Return a new, initialized image cache that is allocated from the
heap. Call free_image_cache to free an image cache. */
DEFUN ("image-flush", Fimage_flush, Simage_flush,
1, 2, 0,
doc: /* Fush the image with specification SPEC on frame FRAME.
-This removes the image from the Emacs image cache. If SPEC specifies
-an image file, the next redisplay of this image will read from the
-current contents of that file.
+ This removes the image from the Emacs image cache. If SPEC specifies
+ an image file, the next redisplay of this image will read from the
+ current contents of that file.
- FRAME nil or omitted means use the selected frame.
- FRAME t means refresh the image on all frames. */)
- (spec, frame)
- Lisp_Object spec, frame;
+ FRAME nil or omitted means use the selected frame.
+ FRAME t means refresh the image on all frames. */)
+ (Lisp_Object spec, Lisp_Object frame)
{
if (!valid_image_p (spec))
error ("Invalid image specification");
\f
/***********************************************************************
File Handling
- ***********************************************************************/
+***********************************************************************/
- static unsigned char *slurp_file P_ ((char *, int *));
+ static unsigned char *slurp_file (char *, int *);
/* Find image file FILE. Look in data-directory/images, then
\f
/***********************************************************************
XBM images
- ***********************************************************************/
+***********************************************************************/
- static int xbm_scan P_ ((unsigned char **, unsigned char *, char *, int *));
- static int xbm_load P_ ((struct frame *f, struct image *img));
- static int xbm_load_image P_ ((struct frame *f, struct image *img,
- unsigned char *, unsigned char *));
- static int xbm_image_p P_ ((Lisp_Object object));
- static int xbm_read_bitmap_data P_ ((struct frame *f,
- unsigned char *, unsigned char *,
- int *, int *, unsigned char **, int));
- static int xbm_file_p P_ ((Lisp_Object));
+ static int xbm_scan (unsigned char **, unsigned char *, char *, int *);
+ static int xbm_load (struct frame *f, struct image *img);
+ static int xbm_load_image (struct frame *f, struct image *img,
+ unsigned char *, unsigned char *);
+ static int xbm_image_p (Lisp_Object object);
+ static int xbm_read_bitmap_data (struct frame *f,
+ unsigned char *, unsigned char *,
+ int *, int *, unsigned char **, int);
+ static int xbm_file_p (Lisp_Object);
/* Indices of image specification fields in xbm_format, below. */
\f
/***********************************************************************
Algorithms
- ***********************************************************************/
+***********************************************************************/
- static XColor *x_to_xcolors P_ ((struct frame *, struct image *, int));
- static void x_from_xcolors P_ ((struct frame *, struct image *, XColor *));
- static void x_detect_edges P_ ((struct frame *, struct image *, int[9], int));
+ static XColor *x_to_xcolors (struct frame *, struct image *, int);
+ static void x_from_xcolors (struct frame *, struct image *, XColor *);
+ static void x_detect_edges (struct frame *, struct image *, int[9], int);
#ifdef HAVE_NTGUI
static void XPutPixel (XImagePtr , int, int, COLORREF);
\f
/***********************************************************************
PBM (mono, gray, color)
- ***********************************************************************/
+***********************************************************************/
- static int pbm_image_p P_ ((Lisp_Object object));
- static int pbm_load P_ ((struct frame *f, struct image *img));
- static int pbm_scan_number P_ ((unsigned char **, unsigned char *));
+ static int pbm_image_p (Lisp_Object object);
+ static int pbm_load (struct frame *f, struct image *img);
+ static int pbm_scan_number (unsigned char **, unsigned char *);
/* The symbol `pbm' identifying images of this type. */
size_t len;
int index;
}
-tiff_memory_source;
+ tiff_memory_source;
static size_t
- tiff_read_from_memory (data, buf, size)
- thandle_t data;
- tdata_t buf;
- tsize_t size;
+ tiff_read_from_memory (thandle_t data, tdata_t buf, tsize_t size)
{
tiff_memory_source *src = (tiff_memory_source *) data;
#endif /* HAVE_GIF */
- long unsigned int width;
- long unsigned int height;
+/***********************************************************************
+ imagemagick
+***********************************************************************/
+#if defined (HAVE_IMAGEMAGICK)
+Lisp_Object Vimagemagick_render_type;
+
+/* The symbol `imagemagick' identifying images of this type. */
+
+Lisp_Object Qimagemagick;
+Lisp_Object Vimagemagick_render_type;
+
+/* Indices of image specification fields in imagemagick_format, below. */
+
+enum imagemagick_keyword_index
+ {
+ IMAGEMAGICK_TYPE,
+ IMAGEMAGICK_DATA,
+ IMAGEMAGICK_FILE,
+ IMAGEMAGICK_ASCENT,
+ IMAGEMAGICK_MARGIN,
+ IMAGEMAGICK_RELIEF,
+ IMAGEMAGICK_ALGORITHM,
+ IMAGEMAGICK_HEURISTIC_MASK,
+ IMAGEMAGICK_MASK,
+ IMAGEMAGICK_BACKGROUND,
+ IMAGEMAGICK_HEIGHT,
+ IMAGEMAGICK_WIDTH,
+ IMAGEMAGICK_ROTATION,
+ IMAGEMAGICK_CROP,
+ IMAGEMAGICK_LAST
+ };
+
+/* Vector of image_keyword structures describing the format
+ of valid user-defined image specifications. */
+
+static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
+ {
+ {":type", IMAGE_SYMBOL_VALUE, 1},
+ {":data", IMAGE_STRING_VALUE, 0},
+ {":file", IMAGE_STRING_VALUE, 0},
+ {":ascent", IMAGE_ASCENT_VALUE, 0},
+ {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":relief", IMAGE_INTEGER_VALUE, 0},
+ {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
+ {":height", IMAGE_INTEGER_VALUE, 0},
+ {":width", IMAGE_INTEGER_VALUE, 0},
+ {":rotation", IMAGE_NUMBER_VALUE, 0},
+ {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
+ };
+/* Free X resources of imagemagick image IMG which is used on frame F. */
+
+static void
+imagemagick_clear_image (struct frame *f,
+ struct image *img)
+{
+ printf("clearing imagemagick image\n");
+ x_clear_image (f, img);
+}
+
+
+
+/* Return non-zero if OBJECT is a valid IMAGEMAGICK image specification. Do
+ this by calling parse_image_spec and supplying the keywords that
+ identify the IMAGEMAGICK format. */
+
+static int
+imagemagick_image_p (Lisp_Object object)
+{
+ struct image_keyword fmt[IMAGEMAGICK_LAST];
+ bcopy (imagemagick_format, fmt, sizeof fmt);
+
+ if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick))
+ return 0;
+
+ /* Must specify either the :data or :file keyword. */
+ return fmt[IMAGEMAGICK_FILE].count + fmt[IMAGEMAGICK_DATA].count == 1;
+}
+
+/* The GIF library also defines DrawRectangle, but its never used in Emacs.
+ Therefore rename the function so it doesnt collide with ImageMagick. */
+#define DrawRectangle DrawRectangleGif
+#include <wand/MagickWand.h>
+
+/* imagemagick_load_image is a helper function for imagemagick_load,
+ which does the actual loading given contents and size, apart from
+ frame and image structures, passed from imagemagick_load.
+
+ Uses librimagemagick to do most of the image processing.
+
+ non-zero when successful.
+*/
+
+static int
+imagemagick_load_image (/* Pointer to emacs frame structure. */
+ struct frame *f,
+ /* Pointer to emacs image structure. */
+ struct image *img,
+ /* String containing the IMAGEMAGICK data to
+ be parsed. */
+ unsigned char *contents,
+ /* Size of data in bytes. */
+ unsigned int size,
+ /* Filename, either pass filename or
+ contents/size. */
+ unsigned char *filename)
+{
- ()
++ size_t width;
++ size_t height;
+
+ MagickBooleanType
+ status;
+
+ XImagePtr ximg;
+ Lisp_Object specified_bg;
+ XColor background;
+ int x;
+ int y;
+
+ MagickWand *image_wand;
+ MagickWand *ping_wand;
+ PixelIterator *iterator;
+ PixelWand **pixels;
+ MagickPixelPacket pixel;
+ Lisp_Object image;
+ Lisp_Object value;
+ Lisp_Object crop, geometry;
+ long ino;
+ int desired_width, desired_height;
+ double rotation;
+ int imagemagick_rendermethod;
+ int pixelwidth;
+ ImageInfo *image_info;
+ ExceptionInfo *exception;
+ Image * im_image;
+
+
+ /* Handle image index for image types who can contain more than one
+ image. Interface :index is same as for GIF. First we "ping" the
+ image to see how many sub-images it contains. Pinging is faster
+ than loading the image to find out things about it.
+ */
+ printf("im ping file %s\n", filename);
+ image = image_spec_value (img->spec, QCindex, NULL);
+ ino = INTEGERP (image) ? XFASTINT (image) : 0;
+ ping_wand=NewMagickWand();
+ MagickSetResolution(ping_wand, 2, 2);
+ if (filename != NULL)
+ {
+ status = MagickPingImage(ping_wand, filename);
+ }
+ else
+ {
+ status = MagickPingImageBlob(ping_wand, contents, size);
+ }
+
+ if (ino >= MagickGetNumberImages(ping_wand))
+ {
+ image_error ("Invalid image number `%s' in image `%s'",
+ image, img->spec);
+ UNGCPRO;
+ return 0;
+ }
+
+ if (MagickGetNumberImages(ping_wand) > 1)
+ img->data.lisp_val =
+ Fcons (Qcount,
+ Fcons (make_number (MagickGetNumberImages(ping_wand)),
+ img->data.lisp_val));
+
+ DestroyMagickWand (ping_wand);
+ /* Now, after pinging, we know how many images are inside the
+ file. If its not a bundle, just one.
+ */
+
+ if (filename != NULL)
+ {
+ printf("im read file %s\n", filename);
+ image_info=CloneImageInfo((ImageInfo *) NULL);
+ (void) strcpy(image_info->filename, filename);
+ image_info -> number_scenes = 1;
+ image_info -> scene = ino;
+ exception=AcquireExceptionInfo();
+
+ im_image = ReadImage (image_info, exception);
+ CatchException(exception);
+
+ printf("im wand from image\n");
+ image_wand = NewMagickWandFromImage(im_image);
+ }
+ else
+ {
+ image_wand = NewMagickWand();
+ status = MagickReadImageBlob(image_wand, contents, size);
+ }
+ image_error ("im read failed", Qnil, Qnil);
+ if (status == MagickFalse) goto imagemagick_error;
+
+
+ /* if(ino == 0) */
+ /* MagickSetFirstIterator(image_wand); */
+ /* else */
+ /* MagickSetIteratorIndex(image_wand, ino); */
+
+ //MagickSetFirstIterator(image_wand);
+
+
+ /* If width and/or height is set in the display spec assume we want
+ to scale to those values. if either h or w is unspecified, the
+ unspecified should be calculated from the specified to preserve
+ aspect ratio. */
+
+ value = image_spec_value (img->spec, QCwidth, NULL);
+ desired_width = (INTEGERP (value) ? XFASTINT (value) : -1);
+ value = image_spec_value (img->spec, QCheight, NULL);
+ desired_height = (INTEGERP (value) ? XFASTINT (value) : -1);
+
+ height = MagickGetImageHeight (image_wand);
+ width = MagickGetImageWidth (image_wand);
+
+ if(desired_width != -1 && desired_height == -1)
+ {
+ /* w known, calculate h*/
+ desired_height = ( (double)desired_width / width ) * height;
+ }
+ if(desired_width == -1 && desired_height != -1)
+ {
+ /* h known, calculate w*/
+ desired_width = ( (double)desired_height / height ) * width;
+ }
+ if(desired_width != -1 && desired_height != -1)
+ {
+ printf("MagickScaleImage %d %d\n", desired_width, desired_height);
+ status = MagickScaleImage(image_wand, desired_width, desired_height);
+ if (status == MagickFalse) {
+ image_error ("Imagemagick scale failed", Qnil, Qnil);
+ goto imagemagick_error;
+ }
+ }
+
+
+ /* crop behaves similar to image slicing in Emacs but is more memory
+ efficient */
+ crop = image_spec_value (img->spec, QCcrop, NULL);
+
+ if(CONSP (crop))
+ {
+ /*
+ after some testing, it seems MagickCropImage is the fastest
+ crop function in ImageMagick. This crop function seems to do
+ less copying than the alternatives, but it still reads the
+ entire image into memory before croping, which is aparently
+ difficult to avoid when using imagemagick.
+ */
+
+ int w,h,x,y;
+ w=XFASTINT(XCAR(crop));
+ h=XFASTINT(XCAR(XCDR(crop)));
+ x=XFASTINT(XCAR(XCDR(XCDR(crop))));
+ y=XFASTINT(XCAR(XCDR(XCDR(XCDR(crop)))));
+ printf("MagickCropImage(image_wand, %d,%d, %d,%d)\n", w, h, x, y);
+ MagickCropImage(image_wand, w,h, x,y);
+ }
+
+ /* Furthermore :rotation. we need background color and angle for
+ rotation. */
+ /*
+ TODO background handling for rotation specified_bg =
+ image_spec_value (img->spec, QCbackground, NULL); if (!STRINGP
+ (specified_bg)
+ */
+ value = image_spec_value (img->spec, QCrotation, NULL);
+ if (FLOATP (value))
+ {
+ PixelWand* background = NewPixelWand();
+ PixelSetColor (background, "#ffffff");/*TODO remove hardcode*/
+
+ rotation = extract_float (value);
+ printf ("MagickRotateImage %f\n", rotation);
+
+ status = MagickRotateImage (image_wand, background, rotation);
+ DestroyPixelWand (background);
+ if (status == MagickFalse)
+ {
+ image_error ("Imagemagick image rotate failed", Qnil, Qnil);
+ goto imagemagick_error;
+ }
+ }
+
+ /* Finaly we are done manipulating the image, figure out resulting
+ width, height, and then transfer ownerwship to Emacs.
+ */
+ height = MagickGetImageHeight (image_wand);
+ width = MagickGetImageWidth (image_wand);
+ if (status == MagickFalse)
+ {
+ image_error ("Imagemagick image get size failed", Qnil, Qnil);
+ goto imagemagick_error;
+ }
+
+ if (! check_image_size (f, width, height))
+ {
+ image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
+ goto imagemagick_error;
+ }
+
+ /* We can now get a valid pixel buffer from the imagemagick file, if all
+ went ok. */
+
+
+ init_color_table ();
+ imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type)
+ ? XFASTINT (Vimagemagick_render_type) : 0);
+ if (imagemagick_rendermethod == 0)
+ {
+ /* Try to create a x pixmap to hold the imagemagick pixmap. */
+ if (!x_create_x_image_and_pixmap (f, width, height, 0,
+ &ximg, &img->pixmap))
+ {
+ image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
+ goto imagemagick_error;
+ }
+
+ /* Copy imagegmagick image to x with primitive yet robust pixel
+ pusher loop. This has been tested a lot with many different
+ images.
+ */
+
+ /* Copy pixels from the imagemagick image structure to the x image map. */
+ iterator = NewPixelIterator (image_wand);
+ if ((iterator == (PixelIterator *) NULL))
+ {
+ image_error ("Imagemagick pixel iterator creation failed",
+ Qnil, Qnil);
+ goto imagemagick_error;
+ }
+
+ for (y = 0; y < (long) MagickGetImageHeight(image_wand); y++)
+ {
+ pixels = PixelGetNextIteratorRow (iterator, &width);
+ if ((pixels == (PixelWand **) NULL))
+ break;
+ for (x = 0; x < (long) width; x++)
+ {
+ PixelGetMagickColor (pixels[x], &pixel);
+ XPutPixel (ximg, x, y,
+ lookup_rgb_color (f,
+ pixel.red,
+ pixel.green,
+ pixel.blue));
+ }
+ }
+ DestroyPixelIterator (iterator);
+ }
+
+ if (imagemagick_rendermethod == 1)
+ {
+ /* Try if magicexportimage is any faster than pixelpushing. */
+ int imagedepth = 24;/*MagickGetImageDepth(image_wand);*/
+ char* exportdepth = imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/
+ /* Try to create a x pixmap to hold the imagemagick pixmap. */
+ printf("imagedepth:%d exportdepth:%s\n", imagedepth, exportdepth);
+ if (!x_create_x_image_and_pixmap (f, width, height, imagedepth,
+ &ximg, &img->pixmap)){
+ image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
+ goto imagemagick_error;
+ }
+
+
+ /* Oddly, the below code doesnt seem to work:*/
+ /* switch(ximg->bitmap_unit){ */
+ /* case 8: */
+ /* pixelwidth=CharPixel; */
+ /* break; */
+ /* case 16: */
+ /* pixelwidth=ShortPixel; */
+ /* break; */
+ /* case 32: */
+ /* pixelwidth=LongPixel; */
+ /* break; */
+ /* } */
+ /*
+ Here im just guessing the format of the bitmap.
+ happens to work fine for:
+ - bw djvu images
+ on rgb display.
+ seems about 3 times as fast as pixel pushing(not carefully measured)
+ */
+ pixelwidth = CharPixel;/*??? TODO figure out*/
+#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
+ MagickExportImagePixels(image_wand,
+ 0, 0,
+ width, height,
+ exportdepth,
+ pixelwidth,
+ /*&(img->pixmap));*/
+ ximg->data);
+#else
+ image_error("You dont have MagickExportImagePixels, upgrade ImageMagick!",
+ Qnil, Qnil);
+#endif
+ }
+
+
+#ifdef COLOR_TABLE_SUPPORT
+ /* Remember colors allocated for this image. */
+ img->colors = colors_in_color_table (&img->ncolors);
+ free_color_table ();
+#endif /* COLOR_TABLE_SUPPORT */
+
+
+ img->width = width;
+ img->height = height;
+
+ /* Put the image into the pixmap, then free the X image and its
+ buffer. */
+ x_put_x_image (f, ximg, img->pixmap, width, height);
+ x_destroy_x_image (ximg);
+
+
+ /* Final cleanup. image_wand should be the only resource left. */
+ DestroyMagickWand (image_wand);
+
+ return 1;
+
+ imagemagick_error:
+ /* TODO more cleanup. */
+ image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil);
+ printf("Imagemagick error, see *Messages*\n");
+ return 0;
+}
+
+
+/* Load IMAGEMAGICK image IMG for use on frame F. Value is non-zero if
+ successful. this function will go into the imagemagick_type structure, and
+ the prototype thus needs to be compatible with that structure. */
+
+static int
+imagemagick_load (struct frame *f,
+ struct image *img)
+{
+ int success_p = 0;
+ Lisp_Object file_name;
+
+ /* If IMG->spec specifies a file name, create a non-file spec from it. */
+ file_name = image_spec_value (img->spec, QCfile, NULL);
+ if (STRINGP (file_name))
+ {
+ Lisp_Object file;
+ unsigned char *contents;
+ int size;
+ struct gcpro gcpro1;
+
+ file = x_find_image_file (file_name);
+ GCPRO1 (file);
+ if (!STRINGP (file))
+ {
+ image_error ("Cannot find image file `%s'", file_name, Qnil);
+ UNGCPRO;
+ return 0;
+ }
+ success_p = imagemagick_load_image (f, img, 0, 0, SDATA(file_name));
+ UNGCPRO;
+ }
+ /* Else its not a file, its a lisp object. Load the image from a
+ lisp object rather than a file. */
+ else
+ {
+ Lisp_Object data;
+
+ data = image_spec_value (img->spec, QCdata, NULL);
+ success_p = imagemagick_load_image (f, img, SDATA (data),
+ SBYTES (data), NULL);
+ }
+
+ return success_p;
+}
+
+/* Structure describing the image type `imagemagick'. Its the same
+ type of structure defined for all image formats, handled by Emacs
+ image functions. See struct image_type in dispextern.h. */
+
+static struct image_type imagemagick_type =
+ {
+ /* An identifier showing that this is an image structure for the
+ IMAGEMAGICK format. */
+ &Qimagemagick,
+ /* Handle to a function that can be used to identify a IMAGEMAGICK
+ file. */
+ imagemagick_image_p,
+ /* Handle to function used to load a IMAGEMAGICK file. */
+ imagemagick_load,
+ /* Handle to function to free resources for IMAGEMAGICK. */
+ imagemagick_clear_image,
+ /* An internal field to link to the next image type in a list of
+ image types, will be filled in when registering the format. */
+ NULL
+ };
+
+
+
+
+DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
+ doc: /* Return image file types supported by ImageMagick.
+ Since ImageMagick recognizes a lot of file-types that clash with Emacs,
+ such as .c, we want to be able to alter the list at the lisp level. */)
- unsigned long numf;
++ (void)
+{
+ Lisp_Object typelist = Qnil;
++ size_t numf;
+ ExceptionInfo ex;
+ char** imtypes = GetMagickList ("*", &numf, &ex);
+ int i;
+ Lisp_Object Qimagemagicktype;
+ for (i = 0; i < numf; i++)
+ {
+ Qimagemagicktype = intern (imtypes[i]);
+ typelist = Fcons (Qimagemagicktype, typelist);
+ }
+ return typelist;
+}
+
+#endif /* defined (HAVE_IMAGEMAGICK) */
+
+
\f
/***********************************************************************
SVG
DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2, 2, 0,
doc: /* Initialize image library implementing image type TYPE.
-Return non-nil if TYPE is a supported image type.
+ Return non-nil if TYPE is a supported image type.
- Image types pbm and xbm are prebuilt; other types are loaded here.
- Libraries to load are specified in alist LIBRARIES (usually, the value
- of `image-library-alist', which see). */)
- (type, libraries)
- Lisp_Object type, libraries;
+ Image types pbm and xbm are prebuilt; other types are loaded here.
+ Libraries to load are specified in alist LIBRARIES (usually, the value
+ of `image-library-alist', which see). */)
+ (Lisp_Object type, Lisp_Object libraries)
{
Lisp_Object tested;
return Qnil;
}
+
void
- syms_of_image ()
+ syms_of_image (void)
{
- extern Lisp_Object Qrisky_local_variable; /* Syms_of_xdisp has already run. */
-
/* Initialize this only once, since that's what we do with Vimage_types
and they are supposed to be in sync. Initializing here gives correct
operation on GNU/Linux of calling dump-emacs after loading some images. */
Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS);
DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay,
- doc: /* Maximum time after which images are removed from the cache.
-When an image has not been displayed this many seconds, Emacs
-automatically removes it from the image cache. If the cache contains
-a large number of images, the actual eviction time may be shorter.
-The value can also be nil, meaning the cache is never cleared.
-
-The function `clear-image-cache' disregards this variable. */);
+ doc: /* Maximum time after which images are removed from the cache.
+ When an image has not been displayed this many seconds, Emacs
+ automatically removes it from the image cache. If the cache contains
+ a large number of images, the actual eviction time may be shorter.
+ The value can also be nil, meaning the cache is never cleared.
+ The function `clear-image-cache' disregards this variable. */);
Vimage_cache_eviction_delay = make_number (300);
+#ifdef HAVE_IMAGEMAGICK
+ DEFVAR_LISP ("imagemagick-render-type", &Vimagemagick_render_type,
+ doc: /* Choose between ImageMagick render methods. */);
+#endif
+
}
+
void
- init_image ()
+ init_image (void)
{
+
}
+
+
/* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9
(do not change this comment) */