NAME

Rivl_FileFormat, Rivl_CreateFileFormat, Rivl_DestroyFileFormat - define new file format for signals

SYNOPSIS

#include <rivl.h>
Rivl_CreateFileFormat (interp, formatPtr)
Rivl_DestroyFileFormat (interp, formatPtr)

ARGUMENTS

Tcl_Interp *interp (in)
The Tcl interpreter.
Rivl_FileFormat *formatPtr (in)
Structure that defines the new file format.

DESCRIPTION

Rivl_CreateFileFormat is invoked to define a new file format for signals. The code that implements a signal file format is called a file format handler. Rivl maintains a list of handlers that can be used to read and write signals to or from a file.

Rivl_DestroyFileFormat destroys a file format previously created with Rivl_CreateFileFormat. The purpose of handlers is to allow sig_read and sig_write (and their im_, seq_, and aud_ versions) to branch to appropriate code based on arguments to the command. The arguments usually include a standard filename and possibly a -format option, but handlers are free to interpret arguments as they see fit. For example, the sequence file handler for reading and writing groups of files is designed to recognize arguments like out%03d.ppm.

A file handler is described by a Rivl_FileFormat structure, which contains the following fields:

typedef struct {
    char *name;
    Rivl_MediaType mediaType;
    Rivl_FileReadProc *fileReadProc;
    Rivl_FileWriteProc *fileWriteProc;
} Rivl_FileFormat;

NAME

formatPtr->name provides a name for the format. This field is currently unused except for debugging.

MEDIA_TYPE

formatPtr->mediaType contains one or more media type constants OR'd together. If the media type indicated by a read or write command name is not included in formatPtr->mediaType, then the handler is skipped. For example, a seq_read will only consult handlers for which formatPtr->mediaType includes RIVL_SEQ). Use RIVL_ANY_MEDIA if you don't care about the media type.

FILE_READ_PROC

formatPtr->fileReadProc contains a procedure for a read command to call when it is searching for a suitable file format handler. formatPtr->fileReadProc must match the following prototype:

typedef int Rivl_FileReadProc(
	Tcl_Interp *interp,
        char *fileName,
	int argc,
	char **argv,
        char *format,
	Rivl_Signal *newSignalPtr)
The read command, such as "im_read foo.jpg", is parsed and passed to fileReadProc as follows: If the file name, format string, and other arguments appear to match the format supported by this handler, and there are no errors, fileReadProc should create a new signal, place the signal in *newSignalPtr and return TCL_OK. This often entails defining a new node class. If the request matches the format but an error is discovered (such as the file is damaged), the procedure should return TCL_ERROR. Finally, if the request does not match the format, the procedure should return TCL_CONTINUE to indicate that another handler should be tried.

FILE_WRITE_PROC

formatPtr->fileWriteProc contains a procedure for a write command to call when it is searching for a suitable file format handler. formatPtr->fileWriteProc must match the following prototype:
typedef int Rivl_FileWriteProc(
	Tcl_Interp *interp,
        char *outFileName,
	int argc,
	char **argv,
        char *format,
	Rivl_Signal outSignal,
	char *progressScript,
	char **dtFileNamePtr)
The write command, such as "seq_write rivl_seq7 out.mpg", is parsed and passed to the handler as follows: If the file name, format string, and other arguments appear to match the format supported by this handler, and there are no errors, fileWriteProc should write the contents of outSignal. The region to write is given by the size property of outSignal: from 0 to size.x for 1D signals such as sequences, and from (0,0) to (size.x','size.y) for 2D signals such as images.

progressScript provides a way for the write handler to report periodic progress. It is taken from the -progressScript option to sig_write, etc. progressScript contains a Tcl command that can be evaluated with Tcl_Eval any number of times during the write process. Each time the string is evaluated, it must be appended with a floating point number between 0.0 and 1.0 representing the approximate percentage of the signal that has been written. The value for a given call should always be greater than that of the previous call. It is acceptable to never call progressScript.

dtFileNamePtr provides a way for the write handler to indicate that an existing file can be copied to satisfy the write (dt stands for "direct transfer"). If the write handler determines that there is an existing file with the right contents, it should place a pointer to a malloc'd string containing the name of that file in *dtFileNamePtr and return TCL_OK. The file will be automatically copied or linked to an output file named by argv[1], and the string pointed to by dtFileNamePtr will be freed. If no direct transfer is possible, the write handler should leave dtFileNamePtr alone.

If the write request matches the format supported by this handler but an error occurs in writing procedure should return TCL_ERROR. If the write request does not match this handler, the procedure should return TCL_CONTINUE to indicate that another handler should be tried.

HISTORY

The design of Rivl_CreateFileFormat is based on Tk_CreatePhotoImageFormat. The main difference is less automatic behavior in exchange for generality. For example, Rivl handlers are individually responsible for parsing options and opening files. This flexibility was necessary to allow handling of I/O formats other than standard files, such as groups of image files for sequences.