Foreign Function Interface (FFI)
********************************

The SXEmacs Foreign Function Interface (FFI for short) adds support for invoking code written in other programming languages from within elisp.  The FFI focuses on interaction with C code, but the basic framework can also be used for interfacing to languages other than C, provided they support to be compiled to binary and linked into a shared library.

The SXEmacs FFI can access sharable object files at runtime and use their definition without relocating or relinking the SXEmacs binary.  The purpose (and main motivation) therefore clearly is to supply elisp programmers with a convenient way to implement features from underlying libraries without even touching the C level.

The FFI feature itself must be considered experimental, though. It is a lot of effort to secure raw library calls from misuse, especially because the SXEmacs error handler has no influence on the events triggered inside of the foreign library.  On the other hand, keeping foreign function calls under exhaustive surveillance would noticably slow down the FFI, if not even limit the capabilities at all.

Basic C Types and Functions
===========================

In order to provide a convenient way to access the standard C library (libc), FFI comes with a set of predefined types and functions.  Of course, you can access other functions and define other types beside the ones in libc.  The discussion here is intended to be a basic introduction to FFI.  To use a specific library see the more general sections Calling Foreign Functions and User-Defined Types.

Predefined FFI data types
-------------------------

The following assortment lists all predefined C data types.  These types are also known as Basic FFI types.  We assume these to be well known and do not explain them further.

  * byte, unsigned byte

  * char, unsigned-char

  * short, unsigned-short

  * int, unsigned-int

  * long, unsigned-long

  * float,

  * double

  * void

  * c-string

  * c-data

As with C data types, the actual meaning of these types depends on the system architecture, but there is no difference between these FFI predefined types and their C-pendant if FFI is run on the same machine.

However, the last two types in the list are special in that they are actually a (pointer char) (in C known as char*), but (as the name suggests) data of this type form a string on C level, or arbitrary chunks of (bytewise-oriented) data which is translated to or translated from an ordinary emacs string.  In constrast, we should mention that the char* is actually solely a pointer to one character, and not a string a priori.

In order to handle arbitrary binary data blocks, the type c-data can be used in conjunction with a size parameter (see The c-data form).  Strings -- the internal representation of data of this type -- are (re-)encoded to binary (i.e. the generic binary coding system) due to Mule issues.

The pointer form
----------------

As mentioned in the previous section, every data type can be pointerised, that is create another FFI-object with the address of the data (not the data itself).  We say such data point to other data.

The syntax for this is the form '(pointer DATA-TYPE), so for example the FFI-type '(pointer int) is the data type int* in C.

The function form
-----------------

In addition to pointerised data, there is a special type modifier to represent function signatures.  Such type-cells are needed to declare function objects.

The syntax for this is the form '(function RETURN-TYPE ARG1-TYPE ... ARGN-TYPE), so for example the FFI-type '(function int int unsigned-int) would be rewritten in C as int some_undefined_name(int, unsigned int).

The return type and at least one argument type are mandatory!  So the syntax for functions without return values, i.e. procedures, is to pass the type void as return type.  Similarly, pass a void as arg1-type for functions without arguments.

The array form
--------------

Arrays in general are finite, indexed sets of unityped data.  That is (informally), a contiguous piece of memory with data slots, where the data slots all have the same type and are enumerated from 0 to size-1.  Accessing a certain slot is achieved by passing its slot number to the accessor function.

The syntax for this type-modification is the form '(array TYPE SIZE), with size being a positive integer.  For example the FFI-type '(array int 20) would be equivalent to the C-syntax int some_undefined_name[20].

The union form
--------------

Unions in general are mutually exclusive variants of data types which are united into a super-type.  More formally, the data in a union is a component projection of a product of many types. Informally, the union is a choice of one datum and (with it) one type at a time out of many ones.  Unions are arranged by named slots of different types.  The slots are accessed by their names.

The syntax for this type-modification is the form:

     '(union NAME
       (SLOT-NAME1 TYPE1)
       ...
       (SLOT-NAMEN TYPEN))

The struct form
---------------

Structures in general are products of other types.  Structures consist of named data slots of different types.  The slots are accessed by their names.

The syntax for this type-modification is the form:

     '(struct NAME
       (SLOT-NAME1 TYPE1)
       ...
       (SLOT-NAMEN TYPEN))

The c-data form
---------------

C-data in general is hard to describe, it is everything which is a contiguous piece of memory, called a block of memory.  Data of this type is represented byte-wise, the internal representation is an emacs string encoded as binary.

The syntax is a cons-cell with the symbol c-data in the car and a non-negative integer in the cdr.  For a (yet) unknown length of a data block one can simply use the non-cons'd version 'c-data.

     ;; block of 40 bytes of arbitrary data
     '(c-data . 40)

     ;; indefinite block of data
     'c-data

FFI type-related functions
--------------------------

 -- Function: ffi-basic-type-p type
     Return non-nil if TYPE is a basic FFI type.

     A type is said to be basic, if it is neither a pointer nor a function, and there is a corresponding built-in type in C.

 -- Function: ffi-type-p type &optional signal-p
     Return non-nil if TYPE is a valid FFI type. If optional argument SIGNAL-P is non-nil and TYPE is not an FFI type, additionally signal an error.

 -- Variable: ffi-type-checker [defaults to: ffi-type-p]
     Function to call when the validity of an FFI type shall be checked.

 -- Variable: ffi-named-types
     Alist of named FFI types with elements of the form (NAME . FFI-TYPE).

 -- Function: ffi-size-of-type type
     Return the size of the foreign type TYPE.

     Valid foreign types are: byte, unsigned-byte, char, unsigned-char, short, unsigned-short, int, unsigned-int, long, unsigned-long, pointer-void, float, double, object, and c-string.

 -- Function: ffi-fixup-type type
     Return FFI type TYPE in a canonical form.

 -- Function: ffi-set-storage-size fo size
     Set the size of the allocated space of FO to SIZE.

Calling Foreign Functions
=========================

Calling FFI functions is a many-step process.  The actual call of an external function is the last step in this chain but can be done repeatedly and almost as comfortable as elisp function calls thenceforth.  The chain to FFI function calls can be summed up as following.

 1. incorporate external library contents

 2. declare function signatures

 3. initialise function arguments

 4. call the function

Hereby, step 1 is independent from the other steps.  It can be interchanged with the other steps arbitrarily, but is mandatory at all.

Incorporate External Library Contents
-------------------------------------

 -- Function: ffi-load libname
     Load library LIBNAME. Return a foreign object handle if successful, or indicate an error if the library cannot be loaded.

     The argument LIBNAME should be the file-name string of a shared object library (usual extension is .so).

     The library should reside in one of the directories specified by the $LD_LIBRARY_PATH environment variable or the more global ld.so.cache.

Note you cannot simply modify the ld.so.cache, instead use the command ldconfig on a suited configuration file.  See your vendor's documentation how to do that.

Loading a library using ffi-load additionally registers this library in a list of already loaded libraries.

 -- Variable: ffi-loaded-libraries
     Alist of loaded libraries with elements of the form (LIB-NAME . FFIO).

There is a raw library loader function without the registration code and without error handling.  However, it is highly suggested to use ffi-load exclusively.

 -- Function: ffi-load-library libname
     Load library LIBNAME. Return a foreign object handle if successful, or nil if the library cannot be loaded.

     The argument LIBNAME should be the file-name string of a shared object library (usual extension is .so).

     The library should reside in one of the directories specified by the $LD_LIBRARY_PATH environment variable or the more global ld.so.cache.

The following example (like all other examples in this section) is taken from ffi-curl.el which comes with the SXEmacs distribution.  We assume the library libcurl.so to exist and to reside in a directory searched by the dynamic loader.

     (ffi-load "libcurl.so")
          => #<ffiobject type=(pointer void) size=4 fotype=2
          foptr=0x8a1dad8>
     ffi-loaded-libraries
          => (("libcurl.so" . #<ffiobject type=(pointer void) size=4 fotype=2 foptr=0x8a1dad8>))

Declaring Function Signatures
-----------------------------

Declaring the signature of a function is quite like reading a library's include file.  The main function to achieve this is ffi-defun.

 -- Function: ffi-defun type sym
     Make and return a foreign object of type TYPE and bind it to the external symbol SYM.

     The argument TYPE should be a function type-cell. The argument SYM should be a string naming a function in one of the loaded libraries.

     If SYM does not exist in any of the loaded libraries, an error is indicated.

     This is like ffi-bind but for function objects.

On the other hand, a library may contain useful variables.  The main directive to bind such variable objects is ffi-bind.

 -- Function: ffi-bind type sym
     Make and return a foreign object of type TYPE and bind it to the external symbol SYM.

     The argument TYPE can be any type-cell. The argument SYM should be a string naming an arbitrary symbol in one of the loaded libraries.

     If SYM does not exist in any of the loaded libraries, nil is returned.

Again, let's look at an example taken from ffi-curl.el

     (setq curl:curl_easy_getinfo
           (ffi-defun '(function int (pointer void) int) "curl_easy_getinfo"))
          => #<ffiobject type=(function int (pointer void) int) size=4 fotype=3 foptr=0x40bfa370>

The ffi-bind function works similarly.

Initialising Function Arguments
-------------------------------

As seen in the previous example, external objects are assigned an (elisp-)internal object which refers to them.  Following this abstraction process, it is kind of obvious that arguments for external functions cannot be passed as internal elisp objects, but have to be converted somehow.

The most user-friendly function to accomplish this task is ffi-create-fo, although it cannot catch all the cases (especially compound types are missing as of November 2005).

 -- Function: ffi-create-fo type val
     Create a foreign object of type TYPE and set its value to VAL.  Return created FFI object.

Note that memory allocation and other administrative tasks are entirely performed within the FFI API without involving the user. That is why we can simply ``convert'' an elisp string to a C string, as the example below will demonstrate.

     (ffi-create-fo 'c-string "foobar")
          => #<ffiobject type=c-string size=4 fotype=0 foptr=0x88e3fdc>

     (ffi-create-fo 'unsigned-int 2299)
          => #<ffiobject type=unsigned-int size=4 fotype=0 foptr=0x89f648c>

The function ffi-create-fo is written in lisp and decomposes to more elementary functions.  We are going to discuss them here flatly since they provide a more sophisticated basis for the handling of foreign objects.

 -- Function: make-ffi-object type &optional size
     Create a new FFI object of type TYPE. If optional argument SIZE is non-nil it should be an integer, in this case additional storage size to hold data of at least length SIZE is allocated.

 -- Function: ffi-set fo val
     Set FO's foreign value to VAL.

Note that currently ffi-set does not work on compound data types, nevertheless there are workaround functions.

The following example will demonstrate the use of make-ffi-object and, in conjunction, ffi-set.

     (setq xmpl-fo (make-ffi-object 'long))
          => #<ffiobject type=long size=4 fotype=0 foptr=0x8937dcc>
     (ffi-set xmpl-fo 20000)
          => 20000
     xmpl-fo
          => #<ffiobject type=long size=4 fotype=0 foptr=0x8937dcc>

     (setq xmpl-fo (make-ffi-object 'c-string))
          => #<ffiobject type=c-string size=4 fotype=0 foptr=0x890158c>
     (ffi-set xmpl-fo "some test string")
          => "some test string"
     xmpl-fo
          => #<ffiobject type=c-string size=4 fotype=0 foptr=0x890158c>
     (ffi-get xmpl-fo)
          => "some test string"

After using make-ffi-object to create foreign objects, always make sure that these were assigned a value before requesting the object's data, or simply always use ffi-create-fo.  In the former case, FFI does not initialise the object with default data, its value is therefore indefinite and may cause a crash of SXEmacs when queried.

Also, check carefully to only assign data which is suited for the underlying C type.  Passing, for example, strings to unsigned-ints or long values to an object of type int may not only result in unexpected behaviour but almost certainly a crash.

Like ffi-create-fo the function ffi-set is a higher level lisp binding.  It decomposes into several raw FFI API functions which are presented here just for completeness.  It is highly advised to exclusively use ffi-set.

 -- Function: ffi-store fo offset val-type val
     Store and return the value VAL of type VAL-TYPE in FO's foreign space at OFFSET.

     VAL-TYPE can be either a basic FFI type or an FFI pointer. If VAL-TYPE is a basic FFI type, then VAL can be an ordinary, but suitable Emacs lisp object. If VAL-TYPE is an FFI pointer then VAL must be an FFI object of the underlying type pointed to.

Calling Functions
-----------------

Now that function signatures are bound and argument data is initialised, we can dare to actually apply functions and operations on our data.  The main function to achieve this is ffi-call-function.

 -- Function: ffi-call-function fo &rest args
     Call a function referred to by FO with arguments ARGS, maybe return a foreign object with the result or nil if there is none.

     FO should be a binding initiated by ffi-defun, and ARGS should be foreign data objects or pointers to these.

Unlike with most Emacs lisp functional bindings foreign functions can be called by reference, this means a function may be passed a foreign object as argument and the function's result will reside in that foreign object.

Before we come to an example, we shall discuss two further functions which ``re-convert'' foreign object data to internal Emacs lisp data.

 -- Function: ffi-get fo &keys type off
     Return FO's value (converted to Emacs lisp compliant form).

     Optional key :TYPE may be used to cast FO to :TYPE, it defaults to the object's assigned type. Optional key :OFF may be used to specify an offset, it defaults to 0.

The backbone function of ffi-get is ffi-fetch, but it is highly advised to exclusively use ffi-get, which in contrast also works for structs, arrays and pointers.

 -- Function: ffi-fetch fo offset type
     Return FO's value (converted to Emacs lisp compliant form). FO is cast to TYPE, and the value is aligned to OFFSET.

Let us now look at the promised example.

     (ffi-load "libcurl.so")
          => #<ffiobject type=(pointer void) size=4 fotype=2 foptr=0x8a1cc78>

     ;; we want: char *curl_escape(const char *string, int length);
     ;; this function takes a usual string and returns a version suitable
     ;; as URI
     (setq curl:curl_escape
           (ffi-defun '(function c-string c-string int) "curl_escape"))
          => #<ffiobject type=(function c-string c-string int) size=4 fotype=3 foptr=0x40bf2e50>

     ;; now prepare the funcall
     (let* ((url "http://foo.org/please escape this<$!=3>")
            (str (ffi-create-fo 'c-string url))
            (len (ffi-create-fo 'int (length url))))
       ;; call the function
       (setq result (ffi-call-function curl:curl_escape str len)))
          => #<ffiobject type=c-string size=4 fotype=0 foptr=0x8906af8>

     ;; now let's see what the escaped form is
     (ffi-get result)
          => "http%3A%2F%2Ffoo%2Eorg%2Fplease%20escape%20this%3C%24%21%3D3%3E"

     ;; and compare to
     (ffi-get result :off 13)
          => "foo%2Eorg%2Fplease%20escape%20this%3C%24%21%3D3%3E"

     ;; and to
     (ffi-get result :type 'char)
          => ?h

Examining and Modifying Foreign Objects
=======================================

In this section we give a quick overview of what else can be done with foreign objects or foreign function definitions.

 -- Function: ffi-object-p fo
     Return non-nil if FO is an FFI object, nil otherwise.

 -- Function: ffi-object-type fo
     Return FO's type.

 -- Function: ffi-set-object-type fo type
     Cast FO to type TYPE and reassign the cast value.

 -- Function: ffi-object-size fo
     Return the size of the allocated space of FO.

 -- Function: ffi-set-storage-size fo size
     Set the size of the allocated space of FO to SIZE.

 -- Function: ffi-address-of fo
     Return the FFI object that stores address of given FFI object FO.

     This is the equivalent of the & operator in C.

 -- Function: ffi-deref fo-pointer
     Return the data FO-POINTER points to.

     This is the equivalent of the `*' operator in C.

 -- Function: ffi-null-p fo
     Return non-nil if FO is a null pointer, nil otherwise. Non-nil may be returned only for pointer types or the type c-string.

 -- Function: ffi-null-pointer
     Return the FFI object that represents a null pointer.

     This is the equivalent of NULL in C.

For foreign arrays, unions and structures, there are accessor functions to modify or fetch portions in the foreign object:

 -- Function: ffi-aref farray idx
     Return the element of FARRAY at index IDX. The slot enumeration starts at 0.

 -- Function: ffi-aset farray idx value
     Store the element VALUE in FARRAY at index IDX. The slot enumeration starts at 0.

 -- Function: ffi-slot-offset type slot
     Return the offset of SLOT in TYPE. SLOT can be either a valid (named) slot in TYPE or nil. If SLOT is nil return the size of the structure.

     (define-ffi-type mystruct
       (struct foo
        (bar int)
        (hey char)
        (baz c-string)))
     (ffi-slot-offset 'mystruct 'baz)
          => 8

User-Defined Types
==================

As usual in most libraries written in C, objects carry an abstract type.  These abstract types can be aliases for the built-in ones, structs or unions composed by more atomic types.

For the bare aliasing of types, there is a macro define-ffi-type, which can also be used to construct unions, as well as arrays.

 -- Macro: define-ffi-type name type
     Associate NAME with FFI TYPE.  When defining global structures or unions, NAME may be nil, in that case NAME is derived from the name of TYPE.

     (define-ffi-type mytype unsigned-long)
          => mytype

Once a type is defined that way, it can be used as if it was a native C-type.

     (ffi-type-p 'mytype)
          => t
     (ffi-size-of-type 'mytype)
          => 4

As mentioned above, we look at the construction of arrays now.

     (define-ffi-type myarray (array unsigned-long 8))
          => myarray
     (ffi-size-of-type 'myarray)
          => 32

Similarly, unions and structs can be defined.  For structs, however, there exists a more dedicated definition function, define-ffi-struct.  This function also defines setter and getter forms which can be used to selectively set or get the slots in a structure.

Getting the value of a slot in a structure defined that way can be done with a function STRUCTNAME->SLOTNAME.  Setting values is achieved by using setf on STRUCTNAME->SLOTNAME.

 -- Macro: define-ffi-struct name &rest slots
     Define a new structure of NAME and SLOTS.

     (define-ffi-struct foo (sl1 unsigned-int) (sl2 char) (sl3 int))
          => (lambda (obj) "
     Common Lisp lambda list:
       (foo->sl3 OBJ)

     " (block foo->sl3 (let* ((--obj--temp-- (gensym "--obj--"))
     (--nv--temp-- (gensym "--nv--"))) (list (list --obj--temp--) (list
     obj) (list --nv--temp--) (let* ((obj --obj--temp--) (nv --nv--temp--))
     (list (quote ffi-store) obj (list (quote ffi-slot-offset) (quote
     (quote foo)) (quote (quote sl3))) (list (quote ffi-slot-type) (quote
     (quote foo)) (quote (quote sl3))) nv)) (list (quote foo->sl3)
     --obj--temp--)))))
     (fboundp #'foo->sl1)
          => t
     (fboundp #'foo->sl2)
          => t
     (fboundp #'foo->sl2)
          => t

Enumerations
------------

A special case of user-defined data are so called enumerations. Basically they are used to simultaneously define a large block of aliases.  These are enumerated (beginning from 0) and are replaced by the according integers during the preprocessor time.

For convenience the SXEmacs FFI interface provides a similar functionality.

 -- Macro: ffi-enum name &optional docstring &rest specs
     Define an enumeration NAME. Optional argument DOCSTRING is a documentation string.

     SPECS can be an arbitrary number of symbols which will be enumerated in the respective order.

     Additionally the cells of SPECS may look like

       foo = bar

     to adhere a symbol foo to the enumeration with the value of the symbol bar (i.e. foo is an alias of bar).

     Moreover, it is possible to set the counter explicitly:

       baz = 5

     would assign a value of 5 to the symbol baz and (by side-effect) set the counter to 6 for the next symbol.

     The defined enumeration will result in a (defconst'd) variable name, the value is an alist of the form

       ((symbol . value) ...),

     where value is the C-value of symbol.

     Furthermore, two functions (named NAME and NAME-value) will be defined.  The first one is a simple lookup function returning the C-value of a passed symbol.  The second does basically the same but returns the representing (elisp) integer of a symbol.  Both functions return nil if the symbol is not in the enumeration.

FFI-bindings for libcurl
========================

The next passages introduce bindings defined on top of the current FFI implementation.  To conceal the poorly conceived documentation of FFI itself we strongly advertise to work out the whole power of FFI by these example application.

cURL is a command line tool for transferring files with URL syntax, supporting FTP, FTPS, TFTP, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE and LDAP.  cURL supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, kerberos, ...), file transfer resume, proxy tunneling and a busload of other useful tricks.

The cURL-API is, like cURL itself, free and open software.  The main entrance to cURL is the curl-easy interface, which ffi-curl.el intends to implement.

The FFI-bindings for libcurl can be classified roughly into guts and main procedures (there is actually only one main procedure).  However, we discuss the guts of the API now.

Low-level functions of ffi-curl.el
----------------------------------

As usual, the function's communication takes place via contextes, hence any of the cURL functions expect a context handle which is initially produced by curl:easy-init.

 -- Function: curl:easy-init
     Initialise curl easy interface and return a context handle.

 -- Function: curl:easy-cleanup ctx
     Clean up context CTX and free resources allocated with it. This function must be called after every easy session.

Remember to always free all requested context handles.  The garbage collector of SXEmacs has no influence on them nor on their allocated memory.

     (let ((context (curl:easy-init)))
       (curl:easy-cleanup context))
          => nil

Having allocated a context handle all cURL functions use it by reference, that is functions change it by side-effect or magically retrieve values from it.

 -- Function: curl:easy-setopt ctx &rest options
     Set OPTIONS for curl transfer in session CTX.

     Options are passed as keyword-value-pairs. Supported keywords are:

       * :url string -- a valid Uniform Resource Locator.

       * :fstream ffi-fo -- a file descriptor to which output is redirected.

 -- Function: curl:easy-perform ctx
     Perform cURL operation on the context CTX.

     To control the behaviour of the session or set options into the context, see curl:easy-setopt.

 -- Function: curl:easy-getinfo ctx what
     Get info from the context CTX about WHAT.

 -- Constant: curl:errors-alist
     Alist of error codes and associated clear-text error messages.

User-level functions of ffi-curl.el
-----------------------------------

All of the prior routines have been used to define a user-level function which can be used without the need to deal with the internals.

 -- Function: curl:download url file &rest options
     Download the contents URL to and write them to FILE. Return 0 on success or an integer specifying an error code.

     Optionally you can specify keywords in OPTIONS. The options are keyword-value-pairs and are set via curl:easy-setopt.

     (curl:download "http://www.sxemacs.org"
       (expand-file-name (make-temp-name "curl") (temp-directory)))
          => 0

FFI-bindings for libWand
========================

The libWand library is the proposed API to the ImageMagick core. Depending on the configuration of ImageMagick it supports many, many different file formats for input and output and comes along with a powerful set of image manipulation commands.

Just like the bindings for libcurl the libWand bindings can be roughly classified into user-level functions and commands, currently there is only one command in this class, and low-level API calls.

Low-level functions of ffi-wand.el
----------------------------------

Let us begin with context handlers.

 -- Function: Wand:make-wand
     Return a newly allocated MagickWand (the context handle of libWand).

 -- Function: Wand:clear-wand wand
     Clear all resources associated with the WAND. This does not free the memory, i.e. WAND can furtherly be used as a context, see Wand:delete-wand.

 -- Function: Wand:copy-wand wand
     Return a cloned copy of WAND. This duplicates everything necessary to get an exact, but independent clone of WAND.

 -- Function: Wand:delete-wand wand
     Delete the WAND. This frees all resources associated with the WAND.

     WARNING: Do not use WAND after calling this function!

 -- Function: Wand:wandp wand
     Return non-nil if WAND is a magick wand, nil otherwise.

     (setq foo (Wand:make-wand))
          => #<ffiobject type=MagickWand size=4 fotype=0 foptr=0x8b38350>
     (Wand:wandp foo)
          => t
     (Wand:delete-wand foo)
          => nil
     (Wand:wandp foo)
          => nil

Input/Output functions of Wand context handles
----------------------------------------------

Now here is an assortment of functions which operate on a Wand.

 -- Function: Wand:read-image wand file
     Read FILE and associate it with WAND.

 -- Function: Wand:write-image wand file
     Write the image associated with WAND to FILE.

 -- Function: Wand:display-image wand
     Display the image associated with WAND.

 -- Function: Wand:get-image-pixels-internal wand from-width from-height delta-width delta-height
     Return a raw string of image pixel data (RGB triples).

 -- Function: Wand:get-image-pixels wand
     Return a raw string of image pixel data (RGB triples).

Image geometry and canvas functions
-----------------------------------

 -- Function: Wand:get-image-height wand
     Return the height of the image in WAND in pixels.

 -- Function: Wand:get-image-width wand
     Return the width of the image in WAND in pixels.

 -- Function: Wand:scale-image wand width height
     Scale the image in WAND to the dimensions WIDTH times HEIGHT.

 -- Function: Wand:crop-image wand x y dx dy
     Crop to the rectangle spanned at coordinates (X, Y) by width DX and height DY in the image associated with WAND.

 -- Function: Wand:flip-image wand
     Mirror the image associated with WAND around the x-axis.

 -- Function: Wand:flop-image wand
     Mirror the image associated with WAND around the y-axis.

 -- Function: Wand:roll-image wand x y
     Rolls (offsets) the image associated with WAND to an offset of X and Y.

Image refinement functions
--------------------------

 -- Function: Wand:increase-contrast-image wand
     Increase the contrast of the image associated with WAND.

 -- Function: Wand:decrease-contrast-image wand
     Decrease the contrast of the image associated with WAND.

 -- Function: Wand:despeckle-image wand
     Reduce the speckle noise in the image associated with WAND.

 -- Function: Wand:enhance-image wand
     Enhance the image associated with WAND.

 -- Function: Wand:equalize-image wand
     Equalise the image associated with WAND.

 -- Function: Wand:normalize-image wand
     Normalise the image associated with WAND.

 -- Function: Wand:reduce-noise-image wand radius
     Reduce the noise in the image associated with WAND.

 -- Function: Wand:posterize-image wand levels &optional ditherp
     Posterize the image associated with WAND, that is quantise the range of used colours to at most LEVELS. If optional argument DITHERP is non-nil use a dithering effect to wipe hard contrasts.

 -- Function: Wand:gamma-image wand level
     Perform gamma correction on the image associated with WAND. The argument LEVEL is a positive float, a value of 1.00 (read 100%) is a no-op.

 -- Function: Wand:median-filter-image wand radius
     Perform median normalisation of the pixels in the image associated with WAND.

 -- Function: Wand:solarize-image wand threshold
     Solarise the image associated with WAND.

 -- Function: Wand:modulate-image wand brightness saturation hue
     Tweak the image associated with WAND.

 -- Function: Wand:negate-image wand &optional greyp
     Perform negation on the image associated with WAND.

Image effects functions
-----------------------

 -- Function: Wand:charcoal-image wand radius sigma
     Simulate a charcoal drawing of the image associated with WAND. The RADIUS argument is a float and measured in pixels. The SIGMA argument is a float and defines a derivation.

 -- Function: Wand:oil-paint-image wand radius
     Simulate oil-painting of image associated with WAND. The RADIUS argument is a float and measured in pixels.

 -- Function: Wand:edge-image wand radius
     Enhance the edges of the image associated with WAND. The RADIUS argument is a float and measured in pixels.

 -- Function: Wand:emboss-image wand radius sigma
     Emboss the image associated with WAND (a relief effect). The RADIUS argument is a float and measured in pixels. The SIGMA argument is a float and defines a derivation.

 -- Function: Wand:wave-image wand amplitude wavelength
     Create a ripple effect on the image associated with WAND. The AMPLITUDE argument is a float and defines the how large waves are. The WAVELENGTH argument is a float and defines how often the waves occur.

Image blurring and sharpening functions
---------------------------------------

 -- Function: Wand:blur-image wand radius sigma
     Blur the image associated with WAND. The RADIUS argument is a float and measured in pixels. The SIGMA argument is a float and defines a derivation.

 -- Function: Wand:gaussian-blur-image wand radius sigma
     Blur the image associated with WAND. The RADIUS argument is a float and measured in pixels. The SIGMA argument is a float and defines a derivation.

 -- Function: Wand:motion-blur-image wand radius sigma angle
     Blur the image associated with WAND. The RADIUS argument is a float and measured in pixels. The SIGMA argument is a float and defines a derivation. The ANGLE argument is a float and measured in degrees.

 -- Function: Wand:radial-blur-image wand angle
     Blur the image associated with WAND. The ANGLE argument is a float and measured in degrees.

 -- Function: Wand:sharpen-image wand radius sigma
     Sharpen the image associated with WAND. The RADIUS argument is a float and measured in pixels. The SIGMA argument is a float and defines a derivation.

 -- Function: Wand:unsharp-mask-image wand radius sigma amount threshold
     Sharpen the image associated with WAND using an unsharp mask. The unsharp mask is defined by RADIUS and SIGMA (defined as in Wand:blur-image). The strength of sharpening is controlled by AMOUNT and THRESHOLD.

User-level functions of ffi-wand.el
-----------------------------------

Mostly, for demonstration purposes, there are two functions which are claimed to be suitable for user interaction.  The only operations they perform are reading an image file, rescaling it to fit into the window, glyphifying it and to insert that glyph into a buffer.

 -- Function: Wand:show-image-file-here file
     Insert a glyph with the image from FILE at current point, scale image to fit the buffer window if necessary.

 -- Function: Wand:show-image-file file
     Insert a glyph with the image from FILE in a dedicated buffer, scale image to fit the buffer window if necessary.