header image Home
Tutorial 2

Added: July 21 2005

THIS IS A BASIC TUTORIAL on understanding the Image Processor scripting language. It borrows liberally from the Image Processor's Help section and hopefully will be user friendly for those who are new to programming and scripting.

A SCRIPT IS A PLAIN TEXT FILE that a program reads in and acts on. In this case the program is MainVision and specifically the section which acts on a script is the Image Processor. There are many different kinds of scripting languages and each can have their own syntax. But because of the nature of programming languages in general you will find many similarities between them and scripting. As a result those of you already familiar with some kind of language will notice that the IP syntax is somewhat "C" like. For those of you new to this what you learn here should help if you go on to learn other languages.

THE ADVANTAGE OF SCRIPTING is you don't need to compile anything. A simple text editor is all you need to change things, the changes you make are reflected immediately upon running the script. The downside is that compiled programs run faster and can ultimately do more but they take much longer to develop.

IF YOU'VE NEVER PROGRAMMED OR SCRIPTED BEFORE you should still be able to create scripts of your own. In time with practice you'll be able to initiate complex effects. What follows will describe the variables. operators, conditionals, functions etc that you need to know before you can start.


PREAMBLE general guidelines

 Because the Image Processor works immediately on any changes you 
 make to a script you may see a series of error messages showing
 up in open Track Windows. This is normal operation don't let it
 throw you off. These error messages are handy for debugging when
 things don't come out as planned. Paying attention to them will
 help you fix your scripts. If you find them annoying close the
 Track Window until you've finished editing.

 To start with we'll look at how some types of values are dealt
 with. From a user's viewpoint the Image Processor isn't aware of
 project resolution or length of effect. As far as its concerned
 those kinds of things have floating point values ranging from 0
 to 1. Whether your project is HDTV or web mpeg the X Y components
 will see the the top left corner as 0 and the bottom right corner
 as 1.

 The same applies to the RGBA colorspace (Red Green Blue Alpha). 
 Each component (channel) can have a value ranging from 0 to 1
 as well. Ignoring the Alpha component for the moment if you were
 to assign the following values in your script ...
		R = 0; G = 0; B = 0;
 ... you've told the Image Processor to interpret the output value
 as black. Using a value of 1 for all the components would make
 the output value white. Values in between give corrosponding
 tones/colors.

 A script can have something called a comment. Comments can be
 descriptive text meant to be read by you (or someone else) that
 act as guidelines or give information. They aren't read by the
 script interpreter and for all intents are invisible to it. In
 this case we use a pair of forward slashes // and everything
 that follows is ignored. They can be on a line by themselves or
 follow a statement as shown in these examples.

// this is a comment on a line by itself

x = 1;   // this is a comment after a statement

 Most everything else is a statement (expression) of some sort and
 needs a delimiter marking its end. For this we use a semi-colon ";"
 It tells the Image Processor to process everything preceeding as
 a block. If you leave it out you'll get error messages and your
 script won't work. Statements can be as simple as assigning a
 variable a predetermined value to being the result of complex
 calculations. The following show a few examples of statements.

x = 1;					// simple assign statement

x = 1-(2*X);				// assign from calculation

x = ctrlangle("Angle",0,"ffaf6e");	// assign from controller

 And statements don't necessarily have to be on lines by themselves.
 If you have a number of short statements or related ones you can
 put them on a single line for compactness as shown here.

R = 0.5; G = 0.75; B = 0.25;		// 3 statements on a line

 Finally you'll see I use a generous amount of space in between
 variables, values, statements etc. I do this because it makes the
 code easier to read. In programmer lingo these spaces are known as
 "whitespace" and you can safely leave them out if you prefer. Like
 this.

R=0.5;G=0.75;B=0.25;			// no whitespace

VARIABLES  a thing that contains a value

 The value of a variable is assigned when you first declare it but
 can be modified later in the script. You give the variable a name
 which for the most part can be anything you choose. The exceptions
 would be naming a variable using a word that's reserved for use by
 the program or using "illegal" characters. The value assigned to
 the variable can be expressed as an integer or floating point. It
 can be a fixed value, the result of calculation, or from an input
 controller. They can be declared any time and pretty much anywhere
 in the script. Here are a few examples of declaring variables.

var1 = 2;		// assign integer value

x = 0.1;		// assign floating point value

BigVar = var1*x;	// assign result of calculation

 The following are examples of how not to assign variables.

MyVar = "some text";	// don't assign text to a variable

if = 1.5;		// don't use reserved words

My+New>Var = 1.5;	// some illegal characters

 The Image Processor provides some predefined variables. These are
 R G B and A (alpha channel). They are your output components and
 you assign either fixed, calculated or passed through values to
 them as you would any other variable.

 If you're a programmer you may have noticed that the variables are 
 declared without any type definition. I believe this is because
 the Image Processor treats everything as a signed floating point
 value by default.

CONSTANTS values passed to you

 Constants are the opposite of variables. You get values from them
 instead of assigning values to them. Despite the name "constant"
 in many cases their value changes dependant on coordinates or
 time.

Rn,Gn,Bn,An	color components from an input, n = input_number
X,Y		the current coordinates
T		current effect time
S		absolute time in seconds
F		absolute frame number
TB		time base (frames per second)
PI		the pi constant (3.1415926)

OPERATIONS math that drives things

 The Image Processor has a simple set of operators that deal with
 calculations and testing values.

ARITHMETIC
*	multiplication
/	division
+	addition
-	subtraction
=	assignment

 The arithmetic operators are used in a normal fashion to calculate
 values. I haven't seen a reference in the IP Help to the order of
 precedence (importance) but will assume its the same as I used for
 listing them. Those who are new to programming please note that
 the assignment operator "=" is not treated as an equals sign in
 this case. It is used to pass values from what's on the right side
 over to a variable on the left side.


LOGICAL
<	less than
<=	less than or equal
==	equal
>=	greater than or equal
>	greater than
!=	not equal

 Logical operators are used to test two values against each other
 in a Logical Expression. Although they can be made up from two
 characters they are treated as one operation by the interpreter.
 Non programmers note that "==" is what's known as the equal
 operator. A Logical Expression takes the form of ...
			x <= 2
 ... and that reads as ...
	first_value is less_than_or_equal to second_value
 ... which in of itself doesn't do a whole lot until you use it
 with the if-else operator. Note to programmers, there are no
 logical AND "&&" or OR "||" operators.


if-else OPERATOR
if ( Logical Expression )
{ statement1; statement2; etc; }
else
{ statement3; statement4; etc; }

 This works just like it does it other programming languages. You
 test a Logical Expression and if true go on to execute whatever
 statements are in that section. If not true there's an alternate
 "else" with its statements. The IP Help describes the if-else
 operator as one operation. I've found its possible to just use
 the "if" part as long as some default values are assigned to RGBA.

 The following example shows a test of the location constant X to
 see if its current value is greater than or equal to half its
 maximum possible value. Then assign a value to the variable var
 based on the result of the test.

if ( X >= 0.5 )
{ var = 0; }
else
{ var = 1; }

 Non programmers should note that in this instance a semi-colon ";"
 is not used. Also notice the type of brackets that are used. The
 section that tests the Logical Expression is a pair of normal
 brackets "( )" and what encloses the statements are braces "{ }".
 For script clarity (or style) you may wish to put the braces on
 their own lines or have the opening brace on the same line as the
 "if" clause as follows in these abbreviated examples.

if ( X >= 0.5 )
{
 var = 0; 
}

if ( X >= 0.5 ){ 
 var = 0; 
}

 Its up to you and mostly a matter of personal preference. When
 you find a style of coding you like keep to it. That will make
 things easier to read and understand when you rework a script
 at a later date.

 Its also possible to perform "nesting" of the if-else operator.
 That is to say once inside the statement section you can again
 call the if-else operator and do more tests as follows in this
 example.

if ( X >= 0.5 ) {
 R = 0; G = 0; B = 0; A = 0;
 if ( Y >= 0.25 ) {
   R = R1/2; G = G1/2; B = B1/2; A = A1/2;
 }
}
else {
 R = R1; G = G1; B = B1; A = A1;
}

 What's happening above is a test of X is made. If true we execute
 the statements inside the braces. First are four statements in a
 row that assign the value 0 to each of the output RGBA components.
 That's followed by a second test on the value of Y which if true
 reassigns new values to RGBA overwriting what was just done above.
 If the original Logical Expression didn't test true then we're at
 the "else" clause which in this case passes the original input
 values unchanged.

 You can use nested if-else operators as a poor man's "switch" and
 create discrete levels of actions. The following example would set
 output values to one of three tones White, Grey or Black.

if ( X <= 1 ) {
 R = 1; G = 1; B = 1; A = 1;
 if ( X <= 0.666 ) {
  R = 0.5; G = 0.5; B = 0.5; A = 0.5;
  if ( X <= 0.333 ) {
   R = 0; G = 0; B = 0; A = 0;
  }
 }
}

 Note to programmers, there are no other conditionals or anything like
 "for", "while" and related loops.

FUNCTIONS work horses

 Sometimes there are operations that are performed repeatedly or
 are very complex and get bundled into what are called functions.
 In the case of the Image Processor the functions are given (or
 passed) a value and will always give back (or return) a value. As
 an example using the function sqrt() ...
		NewVar = sqrt(x);
 ... you've passed it the variable x and the return value (answer)
 is assigned to the variable NewVar. Some functions will need more
 than one value passed to them but always return just one. When
 more than one value is passed use a comma "," to seperate them.



MATH
sin(x)		returns sine
cos(x)		returns cosine
asin(x)		returns arcsine
acos(x)		returns arccosine
sqrt(x)		returns square root
exp(x)		reurns exponent
pow(x,n)	returns x to the power of n
abs(x)		returns absolute value
mod(x,n)	returns remainder of division with n as divisor
cut(x)		returns x normalized in the range of 0 ... 1
min(x1,x2)	returns minimum among x1 and x2
max(x1,x2)	returns amximum among x1 and x2
rnd(x)		returns a random value in the range of 0 ... 1
setrnd(x)	sets the random starting number

 If you understand mathematics then most if not all of the above
 functions should make sense. In some cases they'll save you from
 having to write long complex series of statements and calls to
 the if-else operator. Both min() and max() are simple conditional
 tests and if you need random values there's rnd() and setrnd().


INPUT
inputn(x,y);	creates an input with n as the input number

 This is a special kind of function as its use immediately inserts
 a track Input at the top left of of the Image Processer dialog.
 Pass the input() function a set of X Y coordinates and it returns
 the RGBA values for that track. You can have as many inputs as
 you need and each one is numbered like this ...

		input1(x,y);
		input2(x,y);
		input3(x,y);

 ... and so on. This means the return values (which show up as soon
 as the function loads) are numbered to their corrosponding inputs
 like this ...

	R1 G1 B1 A1   R2 G2 B2 A2   R3 G3 B3 A3

 ... etc. You could then use these to assign values to the output
 components as shown in this example ...

	R = ( R1/3 ) + ( R2/3 ) + ( R3/3 );
	G = ( G1/3 ) + ( G2/3 ) + ( G3/3 );
	B = ( B1/3 ) + ( B2/3 ) + ( B3/3 );
	A = ( A1/3 ) + ( A2/3 ) + ( A3/3 );

 ... which is a simple three way mixer.

 In case you're wondering how we managed to get four return values
 when I said above functions only return one value, its like this.
 In the digital realm everything is just one big long number. Its
 up to the program to cut long numbers into usable chunks. Color is
 represented in 32 bits or 4 bytes with each byte representing the
 value for each of the RGBA components. The Image Processor cuts
 the long number into usable chunks for you so it looks like you
 were given four return values. This is also why you don't need to
 have a variable or use the assignment operator with the input()
 function.

 The value you pass to it is the X and Y locations. They can be the
 program constants X Y or the result of a calculation. Whatever you
 pass as a location gets that RGBA pixel value as a return. 


CONTOLS
ctrlnumber01("Name",default,"RRGGBB");
ctrlnumber("Name",default,from,to,precision,"RRGGBB");
ctrlangle("Name",default,"RRGGBB");
ctrlcolor("Name","component",default,"RRGGBB");

 Controls are a special case function as well. Unlike the input()
 function these pass a value over to a variable you declare. They
 are the only functions that take plain text input (used to name
 the control). When you use one in a script the IP dialog window
 will immediately insert a slider control in the top left and a
 colored control line in the timeline section.

 As with any function you pass values to them. Controls require the
 most numbering from 3 to 6 depending on the control. All controls
 have some elements in common. The "Name" component is the plain
 text you use to give the controller a unique name. Duplicate names
 will cause failure, unpredictable results or at the very least your
 dialog window will be short one controller. And always remember to
 use double quotation marks " " to surround the text.

 There's a default value that is passed. This is the value you want
 to set the control to when the Image Processor first loads it. The
 actual value will depend on that particular control's range.

 The final common element is "RRGGBB" and that's the value you pass
 to give a color to the timeline control line + handles. Its value
 is expressed in Hexadecimal notation which should be familiar to
 anyone who's coded web pages. So each of the RRGGBB components is
 given a value from 00 to ff. Note that the A component is not used
 in this case as Alpha describes transparency. This parameter also
 requires the use of double quotes " ". People familiar with HTML
 or other languages should note that there is no prefix such as "0x"
 or a hash mark "#" required.

 Anything else passed will be specific to that function. Here's a
 brief description and look at each one.


ctrlnumber01("Name",default,"RRGGBB");
 This is a simple generic control and requires only a minimal amount
 of values (parameters) to be passed in. As the function name would
 suggest its used to control numbers. The name is somewhat counter
 intuitive when you first see it as you might guess the 01 is part
 of a numbering system. What that actually stands for is the range
 of values this control affects, from 0 to 1. That means the default
 value must be a floating point number in that range.


ctrlnumber("Name",default,from,to,precision,"RRGGBB");
 This is a more complex version of the preceeding function. There
 are three new parameters called from,to,precision that you pass
 values to. The first from is where you want the control range to
 start. The next to is where the range ends. The precision is an
 integer which describes how many decimal places are used. 

 The default,from,to values may be negative and exceed (-)1. They
 may be expressed as an integer or floating point, in any case the
 Image Processor treats them as floating point. This means they can
 have values that aren't whole numbers.


ctrlangle("Name",default,"RRGGBB");
 To control rotation or spin you would use this function. The
 default value is expressed in degrees. I haven't really used it
 much myself so can't provide more info at this time. 


ctrlcolor("Name","component",default,"RRGGBB");
 As the function name would suggest this one controls color values.
 The extra value you pass in is called "component" and will be one
 of r g b and as shown above be encased in double quotes " ". The
 default value is in the range of 0 to 1.


 Here are a few examples of using these controllers.

anyvar = ctrlnumber01("Special", 0.5, "ffff8a");
complexvar = ctrlnumber("X Shift", -0.25, -1, 1.01, 2, "ffffff");
anglevar = ctrlangle("Rotation", 90, "006fdf");
colorvar = ctrlcolor("Red", "r", 1, "ff0000");

 Be aware that you can not pass variables to control functions.
 Where they require a numeric value you must provide one.

 Programmers note that you can not write your own functions, what
 you see is what you get.

Last Words

NOTHING MUCH TO SAY EXCEPT good luck and I hope that made sense.

Benjammin

 00481 

Links
Main Concept - excellent video software
Virtual Dub - great free video software
EyeDropVideo - royalty free animations, images, audio
Benjammin's POV-Ray Pages - animation tutorials
Benjammin's Music Pages
The Gasworks - always a babe fest
Atomic Linux - automate your home
Benjammin's Software Pages - Linux friendly site