Section 3 - Adding Viewer LUTs and Transformations

To add a LUT or other image transformation to the output stage of the Image Viewer, you need to define a RPI_LUTInfo structure, which looks like:

static RPI_LUTInfo linfo = {
    {
        "Menu Name", 
        "not used",
        "author",
        "version"
        "help URL",        
        "icon name",
    };
    Init,        
    ShutDown,
    LUTSetup,
    LUTCleanup,
    Confidence,
    ParmChanged,
    LUTCreate,
    LUTAutomaticSetup
};
This structure is defined in include/CPI/CPI_LUTProvider.h

Let's look at each of the fields in this structure:

Init - This is called once when RAYZ starts up. It initializes the plugin and defines the user interface elements, if any. It should return CPI_TRUE if there is no error. This routine is optional.

ShutDown - This is called once when RAYZ exits. It should return CPI_TRUE if there was no error. This routine is optional.

LUTSetup - This is called once before each use of the LUT or display converter. It returns a pointer to a private data structure which can be used to hold information between CreateLUT calls. This routine is optional.

LUTCleanup - This is the partner to Setup - it is called when the LUT is finished executing. This routine is optional.

Confidence - This defines the confidence value of this display conversion. It returns a value from 0 to 100 which represents your confidence in correctly displaying the current image. You could decide, for example, that your plugin was only interested in displaying log images; so you could check the image context and return 100 for log images and 0 for linear. This routine is optional.

For reference, the RAYZ built-in display converters have the following confidence values:

Cineview (log images) 85 for log data with a Linear White point < 1.0, otherwise 10
LHG (linear images) 80 for linear data, otherwise 10

ParmChanged - This is called whenever a LUT parameter (created in Setup) is changed by the user. The name of the parameter which was changed is supplied to the programmer. This routine is optional.
The syntax is:

void
ParmChanged( CPI_PrivateData handle,
             const char *parmname )

LUTCreate - This function is called each time the image viewer is asked to update. It is sent an array of CPI_Float32 values. These values have the following meaning:

The programmer takes the incoming LUT and modifies it in some way. The incoming LUT is the concatenation of all color operations the have been applied so far. For this reason, you do not want to set the LUT values, but to modify them.

For example, here is the LUT function for a nonsensical image process that doubles the value of the incoming image. Notice that each channel (red, green, blue, etc) can be treated separately.

void
DoublerCreateLUT( CPI_Float32       *dst,
                  const CPI_Float32 *src,
                  CPI_Int32          values,
                  CPI_Int32          channels )
{
    for ( CPI_Int32 i = 0; i < values; ++i )
    {
        for ( CPI_Int32 c = 0; c < channels; ++c )
        {
            *dst++ = *src++ * 2.0F;
        }
    }
}

LUTAutomaticSetup - Allows you to set up current values before the LUT executes, usually based on the incoming image context. If this routine is not supplied, all values are set to defaults. This routine is optional.
The syntax is:

void
LUTAutomaticSetup( CPI_PrivateData    handle, 
                   CPI_ImageContext   context )

The above routines are called by RAYZ in the following order:
Init           Called when RAYZ starts up (so once per LUT type)

Callback:
   ParmChanged Called whenever a defined parameter is changed by user

Setup          Called once before each use of LUT

Confidence

Automatic Setup

Create LUT

Cleanup

Shutdown

Adding the plugin to the Display Conversion Menu

When the .so file is installed in the appropriate plugins directory, the plugin will be loaded at RAYZ startup, and loaded into the Display Conversion menu automatically.

For example, if this RPI_LUTInfo structure (and appropriate routines, not shown here) is set up as shown, then the Doubler image process will appear in the RAYZ Image Viewer menu, as shown:
static RPI_LUTInfo linfo = {
    {
        "doubler",
        "Doubler",
        "Silicon Grail",
        "v0.1",
        "",
        ""
    },

    DoublerInit,
    DoublerShutDown,
    NULL,
    NULL,
    NULL,
    NULL,
    DoublerCreateLUT,
    NULL
};
Resulting menu entry:    

User Parameters

Some LUTs will have parameters, for example film stock targets, that users need to be able to change. The mechanism for defining these parameters, and returning their values to the LUT creation function, is essentially the same as for regular node parameters in RAYZ plugins.

The parameter names and types are defined in the Init routine. The values are typically queried in the Setup routine, and stored into the PrivateData structure, which functions as a kind of Metadata for LUTs.

For example, let's add a menu and a float parameter to our own LUT. To do this, you add the definitions in the Init() routine, as for the node:

// define an array for the menu labels
static const char *gammamenu[] =
{
    "linear",
    "log",
    NULL
};

// define the UI items
static CPI_Bool
BrighterInit( void )
{
    CPI_Bool    retval = CPI_FALSE;

    cpiAddMenu( "images_are",
                "Images Are",
                0,
                gammamenu,
                NULL,
                NULL );

    cpiAddFloat( "bright",
                 "Brightness",
                 1.0,       // default
                 0.0,       // min value
                 3.0,       // max value
                 CPI_PARM_CLAMPMIN | CPI_PARM_CLAMPMAX,
                 NULL,
                 NULL );

    retval = CPI_TRUE;

    return retval;
}
The result of doing this will be an interface area like this:

Then these values are unpacked and used in the CreateLUT routine. For an example of this, see LUTParams.C.


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

Copyright © 2002 Silicon Grail Inc.
736 Seward Street, Hollywood, CA 90038