1. Changes

1.1 The code generated for the FM pre- and post-increment and

decrement operators (++ and --) is now more efficient.

1.2 A 'Track' subkey has been added to the 'Ctl' key, and the

default thumb-tracking behavior of a slider control has

changed. By default, the proxy preview will NOT be updated

while the thumb of a slider control is being moved; the

proxy will be updated only when the thumb is released. This

default behavior is more acceptable for time-consuming filter

operations. If your filter algorithm is fast, you can specify

the 'Track' key in the 'Ctl' control definition, which will

cause FM to try to update the proxy preview continuously as

the thumb is moved. The 'NoTrack' subkey forces the reverse

(non-tracking) behavior.

The default thumb-tracking behavior may be temporarily reversed

by holding down the SHIFT key while dragging the thumb.

The thumb-tracking behavior for control n may also be changed

programmatically by calling setCtlProperties(n, CTP_TRACK) or

clearCtlProperties(n, CTP_TRACK) from your filter code or event

handler code.

1.3 When you click the '+' (zoom in) or '-' (zoom out) buttons

under the proxy preview, FM will now pause for 0.5 seconds

before updating the preview. This allows you to click several

times in quick succession to change the zoom factor by several

increments before the proxy is updated.

Also, holding down SHIFT or CTRL while clicking one of the zoom

buttons has special meaning: SHIFT '+' and CTRL '+' cause an

immediate zoom to 100%. CTRL '-' causes an immediate zoom to

the smallest scale factor (6%). SHIFT '-' causes an immediate

zoom to the "best fit" scale factor (i.e., to the largest scale

factor that still allows the entire proxy image to be viewed

within the preview window).

1.4 FM now has a predefined "tile buffer" called 'tbuf', which is

allocated large enough to hold all active planes of each tile

as it is processed. To insert a pixel value into the tile buffer,

call the tset() function:

tset(x, y, z, val);

To retrieve a pixel value from tbuf, call the tget() function:

val = tget(x, y, z);

Note that tset() is analogous to pset(), except pset() sets a

pixel in the output (destination) tile; and tget() is analogous

to src(), except src() fetches a pixel from the input (source)


Tbuf is useful when writing two-pass algorithms within a single

ForEveryTile pass: First process pixels from the source image,

writing the results to tbuf; then process pixels from tbuf,

writing the final result to the output image.

2. Bug Fixes

2.1 A potential "wild" store in FM, that could cause unpredictable

behavior, has been eliminated.

3. New Features

3.1 User declaration and initialization of scalar variables of

type 'short', 'int', 'long', 'float', and 'double' is now

allowed within blocks (i.e., enclosed in braces). For



int i, j, radius;

double x, y, z;

double pi = 3.14;

int scaledRadius = ctl(0)/scaleFactor;

double sigma = log(255.0)/4.0;

<code ...>


Note, however, that the 'short' and 'long' types are currently

implemented as type 'int' (i.e., as a 4-byte signed integer),

and that type 'float' is currently implemented the same as

type 'double' (i.e., as an 8-byte floating point number). In

future releases, 'short' will be implemented as a 2-byte integer,

and 'float' will be implemented as a 4-byte floating point


N.B. Array, pointer, structure, union, and enumeration declarations

are still not implemented in this release.

Implementation Restriction: You are currently limited to a total

of approximately 100 user-defined variables in a filter program.

This restriction will be eliminated in future releases.

3.2 The following functions and predefined named constants from the

standard C run-time library are now implemented in FM:













long clock( void );

long time( long *timer );

dword strlen( const char *string );

char *strcpy( char *strDestination, const char *strSource );

char *strcat( char *strDestination, const char *strSource );

int strcmp( const char *string1, const char *string2 );

char *strncpy( char *strDest, const char *strSource, dword count );

char *strncat( char *strDest, const char *strSource, dword count );

int strncmp( const char *string1, const char *string2, dword count );

double fabs( double x );

double ceil( double x );

double floor( double x );

double fmod( double x, double y );

double exp( double x );

double log( double x );

double log10( double x );

double ldexp( double x, int exp );

double pow( double x, double y );

double sqrt( double x );

double fcos( double x ); //temporary name for cos

double fsin( double x ); //temporary name for sin

double ftan( double x ); //temporary name for tan

double acos( double x );

double asin( double x );

double atan( double x );

double atan2( double y, double x );

double cosh( double x );

double sinh( double x );

double tanh( double x );

double hypot( double x, double y ); //non-ANSI

int rand( void );

void srand( unsigned int seed );

4. Known Problems

4.1 There is a slow memory leak in the user-defined symbol table handler

which may cause Photoshop to eventually run out of RAM after many FM

compilations. If this happens, exit and restart Photoshop. This

leak will be fixed in the next release.