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)
image.
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
example:
{
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
number.
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:
CLOCKS_PER_SEC
RAND_MAX
NULL
EXIT_SUCCESS
EXIT_FAILURE
_MAX_PATH
_MAX_DRIVE
_MAX_DIR
_MAX_FNAME
_MAX_EXT
EDOM
ERANGE
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.