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.
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.
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.
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.
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";
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";
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;
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";
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";
Definition
int imageReadOpen
(
IMF_OBJECT *imf
}
Parameter | Type | Description |
---|---|---|
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:
close
, scanline read,
and LUT read
routines into imf
.imf->info.image[0
].Allocate private data defining the file descriptor, etc., and associate them with imf->data
.
Some image files may contain multiple images, e.g., the full image and a thumbnail representation. For this discussion, we will assume that you will only be reading the main image from such files.
The detailed steps are as follows:
ERR_printf
, set imf__err
to IMF_C_CANNOT_OPEN
, and return FALSE
.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 );
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;
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
.
imf->info.settings
. (See IMF_CAPABILITY for details.)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
.
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 );
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.
Definition
int your_scan_read_func
(
POINTER data,
int scan,
POINTER **line_buff
)
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:
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).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
.
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
.
Definition
int your_close_func
(
IMF_OBJECT *imf
)
This function is called whenever Maya is finished reading or writing your image file. Follow these steps to create your close function:
imf->data
and set imf->data
to NULL
. To deallocate the scanline buffer allocated in either imageReadOpen
or imageWriteOpen
, use IMF_chan_free
.IMF_C_NORMAL
if file closing and memory clean-up is successful, and IMF_C_failure_code
if not.Definition
int imageWriteOpen
(
IMF_OBJECT *imf
)
Parameter | Type | Description |
---|---|---|
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:
close
and scanline`
writeroutines to
imf`.imf->data
.Detailed steps are as follows:
ERR_printf
, set imf__err
to IMF_C_CANNOT_OPEN
, and return FALSE
.imf->info
and imf->info.image[0]
to extract attributes about the file being written.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;
Specify the image access routines in imf->scan
and imf->close
.
imf->info.settings
. (See IMF_CAPABILITY for details.)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.
Definition
int your_scan_write_func
(
POINTER data,
int scan,
POINTER *line_buff
)
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:
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).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.
Return IMF_C_BAD_SCAN
, IMF_C_NORMAL
, or IMF_C_READ_ERR
.
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.
Definition
unsigned int imageAccess
Description
This variable specifies the reading and writing methods that your plug-in supports. The constants described are bit fields:
IMF_C_LUT_READ
indicates that your plug-in supports reading palettes from files. A LUT reading function must be defined and assigned to imf->lut_read
in the imageReadOpen
routine.IMF_C_LUT_WRITE
indicates that your plug-in supports writing palettes to files.IMF_C_READ
indicates that your plug-in supports the sequential reading of scanlines.IMF_C_READ_RANDOM
indicates that your plug-in supports the random reading of scanlines.IMF_C_WRITE
indicates that your plug supports the sequential writing of scanlines.IMF_C_WRITE_RANDOM
indicates that your plug-in supports the random writing of scanlines.
The default value is IMF_C_READ
|IMF_C_WRITE
.
Example
This example is for a file that supports look-up tables:
unsigned int imageAccess
= IMF_C_LUT_READ | IMF_C_LUT_WRITE | IMF_C_READ | IMF_C_WRITE;
Information on adding image plug-ins continues in part 2 of Appendix E