Writing Plug-Ins


Overview

This document describes how to write plug-ins that can be used with the video editing system. Each plug-in that you write goes into a single source file, and can be written in C or C++. At run-time, the video editor loads the available plug-ins and makes them available to the user.

To compile a plug-in, just type

% make name.efp
Where your plug-in is named name.c or name.C (for C and C++, respectively.) An .efp file will be built; this is a compiled form of your program that can be loaded by the editor. When it starts, the editor loads all files with the suffix .efp in the current directory.


Debugging

A useful tool for seeing what's going on with your plug-ins is a program called snoop. snoop lets you zoom in on the part of the screen that is under your mouse, which allows you to see magnified copies of individual pixels. We have installed snoop in /usr/class/cs248/support/bin.


Basic Conventions

Plug-ins must do a few specific things in order to be recognized successfully by the video editing system. In the pluginInit function, you must do the following:

Additional Plug-In Parameters

You may have a plug-in where the single time-varying parameter that is passed to it isn't enough to specify its behavior (for example, a plug-in that translates an input image by some (x,y) amount). So that you don't need to hard-code the translation in your program code, the video editor can call another function in your plug-in whenever the plug-in is hooked into a sequence of operations. To do this, add a function to your plug-in with this prototype:

  void startFunction(void)
and in your pluginInit() function, add a line like this:

  options->pluginStart = startFunction;
The start function will be called when the plug-in is applied to a sequence, and you can use this opportunity to prompt the user for input. For example:

int gXTrans, gYTrans;

void startFunction()
{
    char buf[1024];

    /* get some parameters */
    fflush(stdin);
    printf ("Translation amount in X: ");
    gets(buf);
    gXTrans = atoi(buf);
    printf ("Translation amount in Y: ");
    gets(buf);
    gYTrans = atoi(buf);
  
    printf ("Setting translation to %d,%d\n", gXTrans, gYTrans);
}

Accessing Pixels In Images

As with the first assignment, we've provided some macros to help you access the pixels in the images that are passed in to your plug-ins. The EF_Image structure's declaration is this:

  typedef struct _EF_Image
  {

    FOUR_BYTES *pixels;
    short       xSize;
    short       ySize;
  
  } EF_Image;
Individual pixels can be extracted or set in an image using the EF_ImageXY(image, x, y) macro:

  int x, y;
  EF_Image *image1, *result;

  EF_ImageXY(result, x, y) = EF_ImageXY(image1, x, y);
There is also a macro EF_ImageSafeXY(image,x,y) which accesses pixels but makes sure that accesses that are out of bounds are wrapped.

There are also some macros to get or change the value of a pixel. First, store the entire pixel in an int:

  int pixel = EF_ImageXY(image, x, y);
Then, individual components can be extracted and set:

  int red = RED(pixel);
  red *= 2;
  RED(pixel) = red;

  EF_ImageXY(image, x, y) = pixel;
Similarly, GREEN(), BLUE(), and ALPHA() are available.


Examples

Now on to a few examples which should clarify all of the above.

First, a plug-in that takes an image as output and inverts the color in each pixel: invert an image. Note that the time varying parameter is ignored.

Next, a plug-in that replaces part of the image with a checkerboard pattern: checkerboard. Here, the time varying parameter can be used to set the size of the checks in the checkerboard; note how the default range of 0 to 1 of the parameter is remapped to a more useful range for the plug-in.

Finally, one that takes two images as input and returns an image that is the average of them: average two images.


CS248: Introduction to Computer Graphics, Pat Hanrahan, Winter 98