FilterFormula Main Page
4. Language Reference
4.1 General Structure
4.2 Keywords
4.3 Variables, Labels and predefined names
4.4 Numerical Literals
4.5 Comments
4.6 Operators
4.7 Predefined variables
4.8 Defined functions
4.9. Compiler options

4. Language Reference

In this chapter the filter definition language is described. Generally, it follows the general syntax of the "C" language. If there is anything not fully described, the rules of "C" apply.
 

4.1 General structure

Each block consists of a series of statements and expressions that can also be used as statements. Every statement has to be followed by a semicolon.

Several statements can be combined to a compound statement that combines several statements to a comprehensive statement. Those are enclosed with braces:

{ statement1; statement2; ... } This is especially useful for if(), while(), and for() statements to execute several statements according to a condition.

All keywords and variable names must be written as one (there may be no spaces, line breaks etc.) within a name (also in longer operators, like ++, >=, ...), but you are allowed to insert new lines and spaces between them (even within one statement) as many as you like:

wh ile(ii<10) a+
=3;
would be illegal, but while ( ii
< 10 ) a
+= 3
;
would be accepted by the compiler (whatever sense it makes...).
 

4.2 Keywords

The following keywords can be used in your filter source (plus description):
 
init
defines the init-section. The code within this section is executed once before the filtering starts
pass1
defines the code for the first pass.
init1
is executed once between pass1 and the main pass (the main pass needs no special keyword).
if - else
if(expression) statement1 else statement2. If the expression is true, statement1 (or a block of statements eclosed in braces) is executed, otherwise statement2 (the else... part is optional)
while
while(expression) statement ... Execute statement as long as expression is true (not equal zero)
for
for(expression1;expression2;expression3) statement.... execute expression1, then repeat statement and perform expression3, as long as expression2 is true. (just like in "C"). expression1, expression2 and expression3 (and statement) may be empty: for(;;); does an endless loop (should not be used!)
goto
goto label ... jumps to a certain label.
break
leave the current repetitive block (for, while)
continue
stop the execution of the current iteration in a loop and continue with the next.

4.3 Variables, Labels and predefined names

In contrary to "C", in FilterFormula variables do not have to be defined prior to their use, as there is only one variable type:

signed int (32 bit data length)

The names of the variables may have up to 32 characters and are case sensitive. Every variable name has to start with a letter (or underscore character "_") and can be followed by a number of alphanumeric characters (letters, digits or underscore characters). They may not contain (as in "C") special characters like "$", etc..

The names of the variables must not be the same as the names of the functions or the keywords, e.g. a statements

break = 3;
src++;
would cause SYNTAX ERRORs.

Note: If a syntax error is displayed and you do not see the reason for it, check if you named a variable with a predefined symbol (e.g. src ...). Change the name and it should compile properly.

For a list of predefined variables see chapter 4.7.

Labels are defined by appending a colon (":") to the name (Note: there must be no space between name and colon!). This may appear only outside a statement. You can jump to the label by using the goto keyword. E.g. the source lines:

i=0;
labl: i++;
if(i<20) goto labl;
would describe a loop with i=1 to 20, and could be written in a much more elegant way by use of while's and for's. But this also works. Unless there is no absolute need for this construction (e.g. error case), you should not use it as it makes the source code confusing and ununderstandable.

For a label name the same specifications apply as for variable names (up to 32 alpha + alphanumeric characters, case sensitive). You may (but should not) name a label equal to a variable symbol. You must not give it the name of a keyword or a function.
 

4.4 Numerical Literals

Very much as in "C", integer literals are usually written in decimal form (1 to 10 digits with an optional minus sign in front). For special reasons, you can define constants also in hexadecimal form (number system using a base of 16), which are a number of 1 to 8 hex digits (0,1,..9 plus A,B,C,D,E,F - or lowercase), preceded by a "0x" prefix.

In contrary to "C", you cannot define octal constants (those numbers starting with "0" are treated as decimal values and can thus have different values as intended) and character constants as character manipulation absolutely makes no sense in filter definitions.
 

4.5 Comments

As filter definitions are usually quite sophisticated, for a better readability (even if you do not want to distribute the filter, to help your own memory) it is a good thing to add comments to the source that describe what the code really does (or, at least, should do :) ).

Comments can be defined as in "C" or "C++" in two different modes, plus one additional mode specific to FilterFormula:
 

/* comment */
everything between the comment signs is ignored for compilation
// comment
everything after the two slashes to the end of this line is ignored
/. comment
from this point everything to the end of the text is ignored (End of file)


As the source for a filter may have up to 16 Kilobytes (16384 bytes), there is normally plenty of space to add comments.
 

4.6 Operators

The following operators can be used in FilterFormula (they are listed according to their precedence, last is highest). The meaning and usage is the same as in "C" (see an appropriate manual).
  
= += -= *= /=

%= &= |= ^=
as defined in "C" (assignment, add value to, etc...)
, comma operator: evaluates both expressions and use value of the last.
? : if-then: if operator before ? is true, use the expr. between ? and : , otherwise use the expression after the colon
&& || logical AND, OR
& | ^ bitwise AND, OR, XOR
!= == not-equal, equal
< > <= >= comparison operators
<< >> shift left, shift right (arithmetic)
+ - addition, subtraction
* / % multiplication, division, modulo
! ~ logical, bitwise NOT
- ++ -- unary minus, increment, decrement.
The ++ and -- operators can both be used with variables, but in contrary to C, both are treated as preincrement operators (x++ and ++x both have the value of (x+1) ).
The equal ("=") sign (and the "?=" operators) can be used in a serialized manner, that is:
R=G=B=0;
sets the red, green and blue channel values to zero (that is, the output will be black).
 
 

4.7 Predefined variables


In the following, there is a list of variables that are predefined in FilterFormula. They can be, but should not be used for other purposes than defined, as more complex variables (such as d and m) are only calculated if they are used in the code in order to save calculation time (if they were used as auxiliary variables, they would be calculated but these values would never be used).

The following table shows a listing of all variables that have a special meaning in FilterFormula:

(The names in red or indicated with an asterisk (*) do not exist in Filter Factory)
  

R, G, B, A these four variables contain the output values for the red, green, blue and alpha channel (if available) of the current point (x,y) after the filtering process. If you want to change the value of the image channel at the current point, you have to set one of these variables to a value calculated by your filter. They are pre-initialized to r,g,b and a (picture identity)
r,g,b,a original (input) values of the image's red, green, blue and alpha channel at the current point (x,y). You can change these values without actually changing the result of the filtering process. If you want to do so, you must assign values to the uppercase variables (above).
msk (*) represents the value of the mask (selection) of the current pixel. This value can be from 0 (not within the selection mask, changes applied to this pixels cannot be seen after the filtering process) to 255 (all changes are fully visible).
i,u,v values of the current pixel in the YUV color system. These are read only values (they can be read, but you cannot set a pixel in this format) and are calculated from r,g, and b using the following formula (Filter Factory compatible):

i=((76*r)+(150*g)+(29*b))/256; (Y channel)

u=((-19*r)+(-37*g)+(56*b))/256;

v=((78*r)+(-65*g)+(-13*b))/256;

I personally do not see very much use for these variables, but for compatibility reasons they have been implemented....

x,y the coordinate of the pixel that is currently being filtered (x .. horizontal value, y .. vertical value). The range of x is from 0 to X-1 (X is the hor. dimension), y ranges from 0 to Y-1 (vert. dimension).

(0,0) is the upper left corner, while (X-1,Y-1) is the lower right corner.

Filtering is always done from (0,0), through (1,0), (2,0) ... , (0,1), ... (X-1,Y-1) (linewise filtering, similar to television systems).

d,m d is the angle from the image center (X/2,Y/2) to the current point, where a value of 1024 represents the full circle (as 2*PI, in real mathematics). These angle dimensions are used throughout FilterFormula to prevent floating point arithmetics.
m is the distance from the image center (which is calculated according to Pythagoras, by sqr( (x-X/2)2 + (y-Y/2)2 )
X,Y horizontal and vertical dimensions of the image to be filtered.
Z describes the number of channels in the image, which is always three (if no alpha channel is available, i.e. background layers) or four (on layers with transparency)
M maximum magnitude of the images (max. value for m) which is the half of the diagonal of the image.
bgr,bgg,bgb,
fgr,fgg,fgb (*)
current background and foreground color (their red, green and blue components). In every image editing program you can select these two colors (for filling areas, drawing lines etc.). These colors can be accessed by these six variables.
D, dmax = 1024, constant that describes the maximum angle which is always 1024.
dmin = 0 (minimum angle)
mmin = 0 (minimum magnitude)
inpreview (*) returns 1 when called from within the preview window, 
0 when called from the actual filtering process
Note: The constant variables (that is, D,dmax,dmin,mmin) may not be assigned a value as they are internally treated as integer literals.
 

4.8 Defined functions

In the following, you can find a list of functions that can be used in FilterFormula code. The functions that are marked with an asterisk, do not exist in Filter Factory or their usage is changed.

(Remark: the names of the variables do not correspond to the predefined variables, they are just any names.)

All functions, also the trigonometric ones, are done only in integer arithmetics, therefore they could be not as exact as floating point calculations. Be aware that the calculation of the trigonometric functions and square root are quite time consuming as they have to be calculated from tables plus interpolation or by iteration.
 
  

Arithmetic functions
abs(a)  absolute value of a
add(a,b,c) the minimum of the sum of a and b, and c (the same as min((a+b),c))
dif(a,b) the difference of a and b, i.e. the absolute value of (a-b)
sub(a,b,c) the difference of a and b, or c, whichever is greater (the same as max(dif(a,b),c))
max(x,y) returns the maximum (the greater value) of x and y
min(x,y) returns the minimum (the lesser value) of x and y
sqr(a) returns the square root of a (a>0) or 0 (a<=0) (more exactly: the integer less or equal the sqare root)
rnd(x,y) random: calculates a pseudorandom number in the range of x to y (uniformly distributed)
rst(s) random seed: initializes the pseudo-random number generator with value s
scl(x,il,ih,ol,oh) scales x which is in a range of (il..ih) to a range of (ol..oh). This is (except from zero values):
ol+((x-il)*(oh-ol))/(ih-il)
if x<il it returns ol and if x>ih it returns oh
pow(b,pv,pd) (*) returns b(pv/pd), (also for non-integral powers)
Trigonometric functions

The values for the angles reach from 0 to 1024 (corresponds to PI/2 in real arithmetics). Values outside this scope are transformed into it by a modulo operation (both -768 and 1280 have the same results as 256). All angles start at the right and are increased in counterclockwise manner.

cos(x) the cosine of x, the result lies between -512 and +512 (corresponds to -1 to +1 in real arithmetics)
sin(x) the sine of x (the same range as cos() )
tan(x)  the tangent of x, the real life value of 1 results in 512 here (tan(x) equals 512*sin(x)/cos(x) )
c2d(x,y) angle displacement of the pixel at (x,y), that is the angle from the zero origin (0,0) to (x,y). This can be used to calculate the angle betwen two points (x1,y1) and (x2,y2). That would be c2d(x2-x1,y2-y1).
c2m(x,y) the magnitude (distance) of the pixel at (x,y) from the zero origin. That expression equals sqr(x*x+y*y).
r2x(d,m) calculates the x-coordinate of the pixel described by direction (angle) d and magnitude (distance) m.
r2y(d,m) like r2x, but calculates the y-coordinate.
rad(d,m,z) retrieves the channel z of the pixel at an angle of d and a distance of m from the image center (X/2 , Y/2). This function is similar to the predefined variables d and m.
setAngleBase(n) (*) when this function is called, the base value (the representation for PI, or 180°) for trigonometric functions is set to n. If this function is not called, the default value is 512 (Filter Formula compatible).
xmf(typ,v,vdiv,rmul) (*) Extended mathematical functions: Allows to access many otherwise unsupplied mathematical / trigonometric functions from the "C" runtime library. The parameter typ defines the function that should be called. v is the value, and and are scaling values for the parameter and result.
The actual return value is (fun stands for the function which is to be called, e.g. sin() or tan():
return_value = fun(v/vdiv) * rmul

typ can be one of:
0 sin(x*PI)
1 cos(x*PI)
2 tan(x*PI)
3 arcsin(x)/PI
4 arccos(x)/PI
5 arctan(x)/PI
6 sqrt(x)
7 sqrt(1-x2)
8 log(x)
9 log2(x)

Smoothing functions (convolution kernel)

cnv_r(m11,m12,m13,
       m21,m22,m23,
       m31,m32,m33,d)
cnv_g(...),
cnv_b(...),

calculates the convolution kernel for the red, green or blue channel. For this function a mask is layed over the current pixel which contains the eight neibouring pixels. These nine pixel values are each multiplied with the appropriate factor (pixel at (x-1,y-1) is multiplied with m11, the pixel at (x,y-1) with m12, and so on) and added. The result is divided by m (which is usually the sum or the m's).

These functions can be easily used to create simple smoothing filters, emboss filters etc.. These functions are slightly optimized so that it should be a bit faster than calculating this filter in a double for()-loop (which could also be done). But if most factors are 0, it could be better to replace this with calls to the dr, dg, db functions.

Slider and Color functions
ctl(n) return the current value of the slider number n (n = 0.. 7). The range of the output can be defined in the "Options" dialog; the default values (Filter Factory compatible) are 0 to 255.
val(n,minv,maxv)  maps the setting of slider n to a range of minv to maxv. This value is not directly affected by the slider settings in the "Options" dialog. The only possible change could be in the granularity of the function result, if the programmed range of the slider is very small.
map(n,i) item i from mapping table n (i ranges from 0 to 3 and uses the sliders i*2 and (i*2+1) ).

I personally have never used this function and I do not really see the reason for it, but for compatibility reasons we implemented it.

chk(n) (*) returns 1 if checkbox n (n=0 or 1) is checked, 
0 if unchecked
clr(n,z) (*) returns the z-channel of color selector number n
Array functions
get(n) retrieves the value from array index n. If n is outside the defined scope (which can be set in the "Options" dialog, and which is 256 for default), which is 0 to n-1, zero is returned.
put(x,n) sets the array item n to the value x (if n is within the defined range).
The following two functions are two very special-purpose functions that manipulate parts of the array:
calcGamma(gval, start, len) (*)  calculates a gamma curve and stores it in the memory array. gval is the desired (floatingpoint) gamma value times 100 (so that an integer value can be used). A gval of 220 describes a gamma of 2.2 .

This creates a number of lookup table values that are stored in the array starting with start and a length of len. The first value is always 0, the last one always 255 (which corresponds to 1.0 in real arithmetics).

Note: As it is highly time consuming, this function may only be used in the init and init1 sections, but neither in pass1 nor in the main block. In this case the function simply returns 0, but does nothing!

This function can be very easily used to create a gamma correction filter:

init { calcGamma(ctl(0),0,256); }

R=get(r); G=get(g); B=get(b);

where you can control the gamma value with the first slider.
 

sort(start,len) (*) sorts an area of the put/get array from index start to index (start+len-1) with the QUICKSORT algorithm. This can be used e.g. for filters of the "median cut" type. Use this function carefully as it may be very time consuming.
Image source functions
src(x,y,z) retrieves the source value of channel z (z=0 means red, 1 the green, 2 the blue and 3 the alpha channel) at the coordinate (x/y).
dr(dx,dy) (*)  retrieves the red value of the image pixel at coordinates (x+dx,y+dy) (relative to the current coordinate)
dg, db, da (*)  the same for the green, blue, alpha channels
ds(dx,dy,z) (*) channel number z
xsrc(x,y,d,z) (*)  does generally the same as src(), but does bilinear interpolation to obtain smooth pictures. If the coordinates of x and y would be no full integer values, the result is interpolated from the neighbouring pixels as well. As FilterFormula cannot handle non-integer values, the variable d was introduced as a division factor. So the function xsrc(x,y,d,z) returns the source image value of channel number z at the (imaginary) coordinates:

( x/d , y/d )

chv(chn) (*) retrieve the channel number chn of the current pixel. A value of 0 would retrieve the red, 1 the green, 2 the blue, and 3 the alpha channel of the pixel: chv(0)==r, chv(1)==g, etc.

Use this function only to retrieve the values, to set them use the following function:

setCHV(chn,val) (*)  sets the channel number chn of the current pixel with the value specified value (chn ranges from 0 to 3). (Note: it should be written exactly this way, with lowercase "set" and an uppercase "CHV".)

This is equivalent to an assignment to R,G,B, or A, but can be performed in a loop:

for(ii=0;ii<3;ii++) setCHV(chv(ii)+1);

does the same as

{ R=r+1; G=G+1; B=B+1; }

This can be a great advantage especially if the expression on the right side is quite complex and the same for all channels (except the channel), so you do not have to repeat this expression three(four) times.

hue(x,y,z)
lgt(x,y,z)
sat(x,y,z) (*)
calculate the hue, lightness and saturation of the current pixel from the values x,y,z describing the red, green and blue channels. The lightness for the current pixel would therefore be lgt(r,g,b); The range for the functions are:
hue: 0 to 1023 (describes an angle in the color circle),
lgt: 0 to 255 (black to max. lightness)
sat: 0 to 255 (grey to fully saturated)
setHLS(x,y,z) (*) set the R,G, and B variables to the values x (hue), y (lightness) and z (saturation). As in the functions above, the hue ranges from 0 to 1023, while the others range from 0 to 255.

 

4.9. Compiler options

Compiler options are defined in the filter source code by an exclamation sign followed by a text block in braces: !{option=xxx} There must not be any spaces in this block, and you may not use symbolic values instead of literals. No semicolon is needed after the compiler option.

Currently, there is only one compiler option available:

ssize=xxxx describes the size of the put/get memory array (can also be set in the Options.. dialog of the editor window). This setting overrides the interactive one. Example:
!{ssize=512}
defines the size for the memory array as 512 cells (that is 2 KB storage size).



 


Back to Main Page

Previous Chapter
Next Chapter