Appendix E: Adding Image Plug-ins

Maya features an external plug-in module mechanism that lets you create your own image file translators. This system is specific for adding new image types to Maya and is different from the Maya API. These plug-in modules are available whenever you start your application. You can access them through the list of image file types presented where you access image files.

Plug-in image modules are implemented as dynamically shared objects (DSOs or DLLs), and can be written using C or C++. You only need to implement the algorithms that read and write the image files; the user interface and flow control are implicitly handled by Maya.

This document describes the protocol for writing an image plug-in module. It does not describe how to support multiple-frame or movie files. Sample code is provided in the image subdirectory of the Developer Kit.

This section discusses the following:

Once you have written your image file format plug-in, you need to compile it and create a shared object that can be loaded into Maya. We provide a Makefile and buildconfig in our Developer Kit for building the example using the gcc compiler. On Windows, a solution and project file is provided for building the image plug-in with Visual C++. You must first set MAYA_LOCATION before building the image plug-in example. The plug-in that is built must be copied to the $MAYA_LOCATION/bin/plug-ins/image directory before Maya has access to this new image format. Image plug-ins must be built with the compiler and linker flags we provide so that they can be loaded into Maya.

Overview

Maya invokes functions from your image plug-in primarily to read and write image files. One of the places where this can happen is in the rendering window. In this window, you can choose to save your image as a certain format. In addition, you can load an existing rendering image into this window. You are able to select a custom format that you have defined for the read and write operations of this window.

About entry points

Each plug-in must have a defined number of entry points.Maya uses these entry points to determine which features the image plug-in supports.

Some entry points are variables and others are functions. For example, the name of the plug-in is defined by the variable entry point imageName, and the function that opens an image file for reading is defined by the function entry point imageReadOpen.

Some entry points are required, while others are optional. The mandatory entry points are described in the next section. Optional entry points are described in "Optional entry points."

Tip: For your plug-in to be compatible with Maya, you only need to implement the mandatory entry points. The optional entry points of your plug-in may not be invoked by Maya, and therefore are not required.

Mandatory entry points

The following entry points must be defined:

If a mandatory entry point is omitted, the plug-in will not be loaded, and its name will not appear in any menu.

program

Definition

char *program

Description

This entry point specifies the applications that can use the plug-in. This should be Wavefront so that all of your applications can read and write image files supported by this plug-in.

Note: Definition of this entry point is mandatory.

Example

char *program = "Wavefront";

type

Definition

char *type

Description

This entry point denotes the type of plug-in that is being built. A Maya image file plug-in is of type image.

Note: Definition of this entry point is mandatory.

Example

char *type = "image";

version

Definition

char *version

Description

This entry point denotes the version of the protocol for which the plug-in was written. Always use IMF_PROTOCOL_CURRENT.

Note: Definition of this entry point is mandatory.

Example

char *version = IMF_PROTOCOL_CURRENT;

imageKey

Definition

char *imageKey

Description

This entry point specifies a unique key to identify your plug-in.

Note: Definition of this entry point is mandatory.

Example

char *imageKey = "myFormat";

imageName

Definition

char *imageName

Description

This entry point defines the name of your plug-in as displayed in menus. Names should be unique so users can distinguish between them.

Note: Definition of this entry point is mandatory.

Example

char *imageName = "My Image Format";

imageReadOpen

Definition

int imageReadOpen

(

IMF_OBJECT *imf

}

ParameterTypeDescription
imf

Modified

Image File Header

Return Value 

IMF_C_NORMAL if the image was successfully opened; IMF_C_ if an error occurred.

Description

This function is called when a file is to be opened for reading.

The imf parameter contains all of the information necessary for the reading of the file. Before calling imageReadOpen, it contains the filename. After executing this routine, it must also contain pointers to the routines which access the file, information about the size and other attributes of the image being read, buffers to read scanlines of the image into, etc.

The basic steps to writing this function are as follows:

  1. If the filename is not fully qualified, complete it. Then, open the specified file. Continue only if the open was successful. If it fails, you must generate a message using ERR_printf, set imf__err to IMF_C_CANNOT_OPEN, and return FALSE.
  2. Set the image count to be 1, and allocate and initialize one image structure to contain information about this image:

    imf->info.count = 1;
    imf->info.image = malloc( sizeof( IMF_IMAGE ) );
    (void) imf__init_ifd( imf );
    
    
  3. Save the format-specific information describing the file in your own data structure allocated using malloc. This private data structure can contain items like the current file descriptor, last scanline read, active window, etc.:

    private = malloc( sizeof( PRIVATE ) );
    private->... = ...;
    imf->data = malloc( sizeof( POINTER ) );
    imf->data[0] = private;
    
    
  4. Assign your image access routines to imf->scan and imf->close. If your image file contains a look-up table, also specify the routine that reads the look-up table in imf->lut_read.

  5. If your file format defines input capabilities, extract those from imf->info.settings. (See IMF_CAPABILITY for details.)
  6. Read the header information from the file, and store this in your private data structure. You must also define various fields in the imf->info and imf->info.image[0] data structures.

    In the imf->info structure, set the lut_exists field according to whether the image has a look-up table.

    You can also set program, machine, user, date, time, frame number, job_num, and chromaticity information (red_pri, green_pri, blue_pri, white_pt) if these are stored in the file itself.

    You must also set all of the fields in imf->info.image[0]. The aux_format, aux_count, aux_type, and aux_bits fields refer to z channel information. The field curve.gamma needs to be set to either the gamma defined in your file, or the default gamma by calling IMF_def_input_gamma.

  7. Allocate a scanline buffer into which your scanline reading routine reads a row of pixels:

    private_data_ptr->buffer = IMF_chan_alloc(
    imf->info.image, image_width,
    imf->info.key, NULL );
    
    
  8. Return TRUE if your function successfully opened and read the image file header, and FALSE if an error occurred.

    Note: Definition of this entry point is mandatory.

Scanline reading function

Definition

int your_scan_read_func

(

POINTER data,

int scan,

POINTER **line_buff

)

ParameterTypeDescription
data

Input

The private data associated with your image.

scanInput

The scanline to read.

line_buffOutput

The scanline buffer allocated in imageReadOpen, containing the row of pixels read.

Return Value 

IMF_C_BAD_SCAN if scan is outside the image; IMF_C_NORMAL if the scanline was successfully read; and IMF_C_READ_ERR if an error occurred.

Description

This function is called by Maya to read a scanline from your image file. Image files are read according to the image's orientation, either from bottom to top, or from top to bottom.

Follow these steps to create your scanline reading function:

  1. Read the specified scanline. The scanline number is based on bottom-to-top ordering. For example, if your image size is 480 lines, and your orientation is IMF_C_TOP_LEFT, the scanlines are read in the order 479 (top), 478 (second from top), 477, ... 0 (bottom). If the ordering is IMF_C_BOT_LEFT, they are read in the order 0 (bottom), 1 (second from bottom), 2, ... 479 (top).
  2. Transfer the scanline into the buffer allocated in imageReadOpen. The buffer allocated by IMF_chan_alloc contains 8-, 16-, or 32-bit unsigned numbers, according to the number of bits per channel in the file. (The number of bits per channel is rounded up to the nearest number above.)

    Each component of the scanline is stored in a separate contiguous buffer. These are returned in the parameter line_buff, which is an array of pointers to the components that you allocated:

    /*

    * Unsigned char's are used for 1 to 8-bit values;

    * unsigned short's, for 8 to 16-bit values;

    * unsigned long's, for 17 to 32-bit values.

    */

    *line_buff = data->buffer;

    pr = (unsigned char *) data->buffer[0];

    pg = (unsigned char *) data->buffer[1];

    pb = (unsigned char *) data->buffer[2];

    pm = (unsigned char *) data->buffer[3];

    for ( i = 0; i < data->image_width; ++i )

    {

    *(pr++) = red_values[i];

    *(pg++) = green_values[i];

    *(pb++) = blue_values[i];

    *(pm++) = matte_values[i];

    }

    If the file contains a look-up table, you must still return RGB data, and not the indexes into the look-up table, in line_buff.

  3. Return IMF_C_BAD_SCAN, IMF_C_NORMAL, or IMF_C_READ_ERR as appropriate.

    Your scanline reading function must not expect to read the last scanline of the image because Maya may skip the last few scanlines if they do not need to be read. Your plug-in must allow Maya to call your close function at any time after calling imageReadOpen.

Close function

Definition

int your_close_func

(

IMF_OBJECT *imf

)

ParameterTypeDescription
imf

Modified

Image file descriptor.

Return Value 

IMF_C_NORMAL if file closing and memory de-allocation was successful; IMF_C_failure_code if error occurred (for example IMF_C_WRITE_ERR).

Description

This function is called whenever Maya is finished reading or writing your image file. Follow these steps to create your close function:

  1. Close the image file.
  2. Deallocate any private data pointed to by imf->data and set imf->data to NULL. To deallocate the scanline buffer allocated in either imageReadOpen or imageWriteOpen, use IMF_chan_free.
  3. Return IMF_C_NORMAL if file closing and memory clean-up is successful, and IMF_C_failure_code if not.

imageWriteOpen

Definition

int imageWriteOpen

(

IMF_OBJECT *imf

)

ParameterTypeDescription
imf

Modified

Image file descriptor.

Return Value 

TRUE if the image was successfully opened; FALSE if an error occurred.

Description

This function is called when a file is to be opened for writing.

The imf parameter contains all of the information necessary to write the file. Before calling imageWriteOpen, it contains the filename. After executing this routine, it must also contain pointers to the routines that access the file, information about the size and other attributes of the image being written, etc.

The basic steps to creating this function are as follows:

Detailed steps are as follows:

  1. Open the specified file. Continue only if the open was successful. If it fails, you must generate a message using ERR_printf, set imf__err to IMF_C_CANNOT_OPEN, and return FALSE.
  2. Use imf->info and imf->info.image[0] to extract attributes about the file being written.
  3. Save the format-specific information describing the file in your own data structure allocated using malloc. This private data structure can contain items like the current file descriptor, active window, etc.:

    private = malloc( sizeof( PRIVATE ) );
    private->... = ...;
    imf->data = malloc( sizeof( POINTER ) );
    imf->data[0] = private;
    
    
  4. Specify the image access routines in imf->scan and imf->close.

  5. If your file format defines output capabilities, extract those from imf->info.settings. (See IMF_CAPABILITY for details.)
  6. Write the file header and look-up table, if defined.
  7. Return IMF_C_NORMAL if your function successfully opened and read the image file header. Return IMF_C_failure_code if an error occurred.

    In the event of a failed attempt at opening an image file, Maya calls imf__free_obj( imf ) to free the IMF_OBJECT passed to imageWriteOpen. Therefore, you must not call imf__free_obj in your error-handling code.

    Note: Definition of this entry point is mandatory.

Scanline writing function

Definition

int your_scan_write_func

(

POINTER data,

int scan,

POINTER *line_buff

)

ParameterTypeDescription
data

Input

The private data associated with your image.

scanInput

The scanline to be written.

line_buffOutput

Buffer containing the pixels for the current scanline.

Return Value 

IMF_C_BAD_SCAN if scan is outside the image; IMF_C_NORMAL if the scanline is successfully written; and IMF_C_WRITE_ERR if an error occurs.

Description

This function is called by Maya to write a scanline to your image file. Image files are written according to the image's orientation, either from bottom to top, or from top to bottom.

Follow these steps to create your scanline writing function:

  1. Write the specified scanline. The scanline number is based on bottom-to-top ordering. For example, if your image size is 480 lines, and your orientation is IMF_C_TOP_LEFT, the scanlines are written in the order 479 (top), 478 (second from top), 477, ... 0 (bottom). If the ordering is IMF_C_BOT_LEFT, they are written in the order 0 (bottom), 1 (second from bottom), 2, ... 479 (top).
  2. Retrieve the red color channel information from line_buff[0], green from line_buff[1], and blue from line_buff[2], where line_buff is the scanline buffer passed in by Maya. If there is a matte channel, it is in line_buff[3]. The z channel, if it exists, is in line_buff[4]. The pixels are stored from left to right.

    pr = (unsigned char *) line_buff[0];
    pg = (unsigned char *) line_buff[1];
    pb = (unsigned char *) line_buff[2];
    pm = (unsigned char *) line_buff[3];
    for ( i = 0; i < data->image_width; ++i )
    {
       red_values[i] = *(pr++);
       green_values[i] = *(pg++);
       blue_values[i] = *(pb++);
       matte_values[i] = *(pm++);
    }
    
    

    Convert the values to the format used by your file format and write the scanline to the file.

  3. Return IMF_C_BAD_SCAN, IMF_C_NORMAL, or IMF_C_READ_ERR.

Optional entry points

A number of additional entry points exist. If an optional entry point is not defined, a default value is used. Some optional entry points are ignored unless the feature is supported by your file format.

imageAccess

Definition

unsigned int imageAccess

Description

This variable specifies the reading and writing methods that your plug-in supports. The constants described are bit fields:

Information on adding image plug-ins continues in part 2 of Appendix E