Return to the tutorials


Writing an HDR Shop Plugin

Note that this section requires knowledge of C or C++.

HDRShop supports a flexible plug-in architecture that lets a user write a new image editing operation and integrate it with the HDRshop interface. Plug-ins are special stand-alone command-line programs that receive parameters via the command-line arguments. Because the interface with HDRShop uses command-line arguments and the standard pipes, a plug-in can be written in any language and perform arbitrary processing on an image. For this tutorial, we will assume the language of choice is C++.

We will illustrate how to write a plug-in with a simple example plug-in that blurs an image and optionally halfsizes the image as well.

The plug-in communicates with HDRshop via the stdin stream. When the plugin is invoked with a single command-line argument "--help" or "/?" it must output its list of parameters in a specific format and then exit. Our plug-in will output the following message to stderr:

This is a simple test plugin to blur an image.
HDRSHOPFLAGS:
HDRSHOPVERSION: 1.0.1
USAGE: sample_plugin [input.pfm] [output.pfm] [options]
OPTIONS:
/V:[int=10] Blur Variance
/D Downsample 50%

The plugin must list information about itself in the following blocks:

Options are specified one per line. Each option has an identifier string, an optional parameter descriptor, and a description string. Each line should begin (ignoring whitespace) with an identifier string. For example, "/V:" and "/D" are the identifier strings in our sample plugin. The identifier is terminated by either whitespace or a parameter descriptor. This gives us a little bit of leeway as to how we want to specify our options; if we wanted, we could instead use "--variance=", or "-downsample" as identifiers.

Parameter descriptors are enclosed in square brackets: [], except for a multiple-selection, which is surrounded by curly braces: {}. Inside the square brackets is the descriptor type, followed by an optional default value. If a default value is specified, then HDR Shop will initialize the option's generated user interface to that value. The available parameter descriptor types are:

Type Descriptor Default Example (identifier + descriptor) Notes
boolean   false /downsample If this option is present on the command line, the value is true, otherwise false
integer [integer=X],[int=X] X --iterations=[int=6]  
string [string=X],[str=X] X /greeting:[string=Hello World!]  
float [float=X] X /pi=[float] In all cases, if the user specifies no value for an option,
that option is not sent as a command-line argument.
input
filename
[inputfilename=X] X /C:[inputfilename=my default.cfg] Specifies a file that the plugin will read
output
filename
[outputfilename=X] X /debugout=[outputfilename=debug.txt] Specifies a file that the plugin will write
rectangle [selection] See notes /s[selection] The user-interface for this option is a checkbox, defaulting to checked.
When checked, the current selection in HDRShop will be sent to the plugin,
in the format: 100,100,200,200 (that's top,left,bottom,right).
If there is no selection, the size of the entire image is returned.
multiple
choice
{String1|String2|...|StringN} String1 --algorithm:{|fast|accurate|weird} Multiple selection from the given list of strings.
The first value is the default.

When the plugin is selected by the user, HDRShop will execute "sample_plugin --help" and parse the resulting text. HDRShop will then create a dialogue box where the user can enter the values of all the plugin options. When the user has selected the options and clicks "Execute," HDRShop will call the plugin again, this time with all of the options packaged as command line arguments. Options are passed to the plugin in the same format they are specified above. For example, if the user selects a "Blur Variance" value of 15, HDRshop will pass the command-line argument /V:15. If the user has selected the "Downsample" option, HDRShop will pass the argument /D, otherwise it will leave off the argument.

For plugins that manipulate images, HDRShop passes them as .pfm files. See below for details on how to parse these files. HDRShop writes the current image to a temporary .pfm file, which it passes the plugin. If the plug-in is supposed to return in image to HDRShop, HDRShop specifies the name of the temporary file that the plugin should save the .pfm file to.

Now lets get to the actual source code for the plugin:

int main(int argc, char *argv[])
{
char *inputfilename = 0;
char *outputfilename = 0;
int downsample = 0;
int variance = 10;

if (argc == 1) {
printHelp();
exit(0);
}

for (x = 1; x < argc; x++) {
if (argv[x][0] == '-') {
if (argv[x][1] == '-') {
if (strncmp("help", &argv[x][2], 4) == 0) {
printHelp();
exit(0);
}
}
}
else if (argv[x][0] == '/') {
switch(argv[x][1]) {
case '?':
printHelp();
exit(0);
break;
case 'V':
variance = atoi(argv[x]+3);
break;
case 'D':
downsample = 1;
break;
}
}
else {
if (inputfilename == 0)
inputfilename = argv[x];
else
outputfilename = argv[x];
}
}
...

This section parses the command line arguments. If the program is passed /? or --help, it calls printHelp() which prints the message detailed above to stderr and then exits. Otherwise, the program looks for the forward-slash flag to indicate command line options. If the option is ?, it prints the help message. Otherwise, if the option is V, it parses the remaining part of the string for the integer value of variance. If the option is D, it sets the downsample flag to true. Finally, if the command line argument is not an option, it is assumed to be the input filename. If the input filename has been read, it is assumed to be the output filename.

	if (!inputfilename)
doError(1);
if (!outputfilename)
doError(2);

floatimage fimg;
if (!fimg.LoadPFM(inputfilename))
doError(3);

fimg.fast_gaussian_blur(variance);
if (downsample)
fimg.halfsize();

if (!fimg.SavePFM(outputfilename))
doError(4);

return 0;
}
The function doError() just prints an error string to stderr and then calls exit() with a nonzero value to indicate to HDRshop that an error occurred. HDRshop will display everything that was output to stderr to the user as an error message. The floatimage class is a utility class. It provides a number of useful functions like file i/o from various formats, antialiased pixel reads, bluring, convolution, and other utilities. The full source code for floatimage and this sample plug-in is availible for download here .

Once the plug-in has been compiled into a working executable, it must be placed in a subdirectoy called "plugins" that is in the same directory as the HDRShop executable. The name of the plug-in will appear in the plugins pulldown menu.


Return to the tutorials