Skip to content

Jiffle runtime

Andrea Aime edited this page Jul 14, 2020 · 3 revisions

The Jiffle run-time system

Once you know how to write a Jiffle script, the next thing you'll want to do is run it. Jiffle provides a number of ways to do that. All of them involve these basic steps:

  • Compile your script into a run-time object.
  • Provide the run-time object with source and destination images (and possibly coordinate information)
  • Execute the object.
  • Retrieve the results (images and/or summary values).

Although you write your script in the Jiffle language, you run it from within Java (or possibly another JVM language such as Groovy).

Compiling and running scripts with JiffleBuilder

Using JiffleBuilder is the easiest way to get started with Jiffle. Let's look at running the following script:

// This script implements a max filter with a 3x3
// neighbourhood (kernel)

// Set option to treat locations outside the source image
// area as null values
options { outside = null; }

foreach (dy in -1:1) {
  foreach (dx in -1:1) {
      values << src[dx, dy];
  }
}

dest = max(values);

This script implements a MAX filter: a 3x3 kernel is placed over each pixel in the input image, represented by the variable src, and the maximum value found is written to the output image, represented by dest.

Now let's look at a Java method which takes the script (in the form of a file) and an input image, and uses JiffleBuilder to run the script, returning the resulting image to the caller.

public RenderedImage buildAndRunScript(File scriptFile, RenderedImage inputImage) 
        throws JiffleException {
    
    JiffleBuilder builder = new JiffleBuilder();
    
    builder.script(scriptFile).source("src", inputImage);
    builder.dest("dest", inputImage.getWidth(), inputImage.getHeight());
    builder.run();
    
    return builder.getImage("dest");
}

JAI integration with JiffleOpImage

The Jiffle OpImage allows the integration of Jiffle scripts in JAI processing chains.

The following example is a source-less script that generates a "sequential" image (one where pixels contain a sequence of integer, starting from one and increasing in the right/down direction):

ParameterBlockJAI pb = new ParameterBlockJAI("Jiffle");

String script = "dest = y() * width() + x();" ;

pb.setParameter("script", script);
pb.setParameter("destName", "dest");

Rectangle bounds = new Rectangle(0, 0, WIDTH, WIDTH);
pb.setParameter("destBounds", bounds);

RenderedOp op = JAI.create("Jiffle", pb);
RenderedImage result = op.getRendering();

assertResult(result, script);

The following example instead uses the JiffleDescriptor to create a simple sum of two images, named a and b in the script, and casts the output to the integer data type:

RenderedImage src1 = buildTestImage(10, 10);
    RenderedImage src2 = buildTestImage(10, 10);
    RenderedOp op =
            JiffleDescriptor.create(
                    new RenderedImage[] {src1, src2},
                    new String[] {"a", "b"},
                    "res",
                    "res = a + b;",
                    null,
                    DataBuffer.TYPE_INT,
                    null);

In case source and destination names are un-specified, Jiffle OpImage defaults to src, src1, src2, ... for the inputs, and res for the output.