Chapter 2 - General Plugin Description

The plugin routines available to the programmer are divided into two categories, CPI and UPI. The UPI routines (User Plugin Interface) are called by Chalice, and provide entry points for the programmer's code. The CPI routines (Chalice Plugin Interface) are functions provided by Chalice; they allow the programmer to get information to and from Chalice.
All of the UPI routines are optional, and Chalice provides sensible default behavior for routines which are not provided.

The Structure of a Plugin

While there are many correct ways to construct the code for a plugin, we are going to demonstrate a format that works and that we recommend. Advanced users may wish to work in other ways. The minimum plugin is the empty file, but that is not useful or interesting, so we'll skip it and talk about the minimum specification for a plugin that actually does anything. This plugin needs to define several actions to Chalice:
  • UI setup - what parameters to show the user
  • initialization - what happens when a new image is plugged into the node
  • updating - what happens when parameter values change
  • execution - what to do when cooking an image
  • The null node might look like this:
    #include <stdlib.h>
    #include <stdio.h>
    #include <limits.h>
    #include <memory.h>
    #include "cpi.h"
    
    CPIDSOEXPORT void upiCreateParameters( void )
    {
    }
    
    CPIDSOEXPORT int upiProcessImage( CPI_Image *result )
    {
    }
    
    In fact, because Chalice supplies stubs for all the routines that you MIGHT define, you don't even need to have these - these empty routines are the default anyway. But this shows the structure of the node code.

    To do useful work, you will probably need some more routines - at the very least, a routine to actually do something to each pixel. This routine would be called by upiProcessImage(), and would be passed the image to work on, plus whatever other information was needed. In practice, a barebones node would look like this:

    template <class T>
    int UserRoutine( T *image )
    {
    	/* do some work on the image */
    }
    
    CPIDSOEXPORT int upiProcessImage( CPI_Image *result )
    {
    	switch( result->info.pelType )
        {
            case P_INT8:
            {
                UserRoutine( (unsigned char)result->data );
                break;
            }
            case P_INT16:
            {
                UserRoutine( (unsigned short)result->data );
                break;
            }
            case P_FLOAT32:
            {
                UserRoutine( (float *)result->data );
                break;
            }
            default:
                cpiError( "Unknown pixel type" );
                return 1;
        }
        return 0;
    
    }
    
    This shows the use of the template to code the routine one time, and let the compiler construct the other alternative versions. upiProcessImage() typically doesn't do much more than make sure the inputs are correct, and then hand off to the user-written routine to do the actual work.

    Makefile and Compile Issues

    The user plugin is saved in a file that ends in .C, for example MyPlugin.C. To compile this on the command line, you would do this:
    > CC -shared -o MyPlugin.so MyPlugin.C -all libcpi.a
    
    This tells the C++ compiler to make a shared object file (suffix .so) which can be dynamically linked by Chalice when it starts running. The "-all" option tells the compiler to include all the symbols from libcpi.a.

    The result of the compile, assuming no syntax errors, is a file called MyPlugin.so

    In order to compile this properly, you will need to have the following files in the directory where you are compiling:

  • cpi.h
  • libcpi.a
    These can be found in the standard Chalice distribution, typically under /usr/grail/chalice1.6/support/src/plugIn
    Copy these files to your working directory.
    You can also leave these in the distribution directory, and direct the compiler to them. This is easier if you are using "make" to compile your software.
    A Makefile is included in the distribution directory - you may copy this to your working directory and add lines for the plugins you wish to work on.
    For example, to add MyPlugin to the Makefile, you would edit it to look like this:
    DSOCPPFILES =   \
        Tile.C      \
        Solarize.C  \
        Gaussian.C  \
        Dither.C    \
        MyPlugin.C	\
        Normalize.C
    
    and then issue the command
    smake MyPlugin.so
    
    (note the use of 'smake' rather than make)

    Installing Plugins

    Chalice looks for plugins in the location defined by the environment variable CHALICE_PLUGINS_PATH. So you can either set your CHALICE_PLUGINS_PATH to point to your development directory, or move the plugin into one of the directories in the CHALICE_PLUGINS_PATH. The default value for this path is /usr/grail/chalice1.6/plugIns (or wherever you have installed Chalice). If you attempt to put your plugins there, you will need root permission.

    A useful way to set this up is to define the path to first look in the default location, then look in your development directory. You would do this with the line

    > setenv CHALICE_PLUGINS_PATH ${CHALICE_PLUGINS_PATH}:`pwd`

    or by putting a similar line into your .login file.
    Plugins can be left in your development directory, in which case Chalice has to be told to look there

    Dialog files

    Chalice needs to build what is called a "dialog" file. This contains the information about what the user interface will look like. Chalice automatically builds these from the list of parameters in the plugins.

    However, the first time you install a plugin, or whenever you change its parameter list or other UI attributes, you need to (re)build the dialogs.

    This is done by running the "builddialogs" program. This creates a file in /usr/grail/chalice1.6/support/config/Dialog/chalice, so you will probably need to run builddialogs as root. This needs to be done everytime you change the parameters in your plugin.

    > su
    Password: *********
    > builddialogs MyPlugin
    
    Now running Chalice should find the plugin and its dialogs.

    Summary:

    To compile and build a plugin:
    1) compile it
    > CC -shared -o MyPlugin.so MyPlugin.C -all libcpi.a
    2) make sure Chalice can find it
    either
    > cp MyPlugin.so /usr/grail/chalice1.6/plugIns
    or
    > setenv CHALICE_PLUGINS_PATH ${CHALICE_PLUGINS_PATH}:`pwd`
    The second choice will only have to be done once, the first must be done after each compile.
    3) build dialogs, if new plugin or parameters have changed
    > builddialogs MyPlugin
    4) run chalice and test
    > chalice

    [Previous Page] [Next Page]
    [Table of Contents] [Index]

    Copyright © 1998 Silicon Grail Inc.
    710 Seward Street, Hollywood, CA 90038