1. New Features
--------------- 1.1 Two new FM specifications have been added (Organization and URL). 1.1.1 The format of the Organization specification is: Organization:"<name of your organization>" Use this specification to supply the name of your organization for use in the plug-in's VS_VERSION_INFO resource and elsewhere. The string containing the Organization specification is available in the new FM built-in variable filterOrganizationText, or as format specifier '!O' within an FM-formatted string. 1.1.2 The format of the URL specification is: URL:"<http://www.example.com>" Use this specification to supply the URL of your website for use in the plug-in's VS_VERSION_INFO resource and elsewhere. The string containing the URL specification is available in the new FM built-in variable filterURLText, or as format specifier '!U' within an FM-formatted string. 1.2 FM now sets the following fields in the VS_VERSION_INFO resource in a standalone filter. (These fields can be viewed by selecting the plug-in in Windows Explorer and choosing File/Properties/Version from the menu bar.) File version: Set from the FM Version: specification. Description: Set from the FM Description: specification. Copyright: Set from the FM Copyright: specification. Author: Set from the FM Author: specification. Comments: Set to "Generated by FilterMeister®". Company Name: Set from the FM Organization: specification. Internal Name: Set to "AfhFM04". Language: Set to "English (United States)". Legal Trademarks: Set to "FilterMeister is a trademark of AFH Systems Group". Original Filename: Set to the base file name to which the plug-in was saved. Product Name: Set from the FM Title: specification. Product Version: Set from the FM Version: specification. URL: Set from the FM URL: specification if present. 1.3 A new built-in function, chooseColor(), invokes the host application's default color picker dialog to allow the user to select an RGB color. The form of a call to chooseColor() is: rgb = chooseColor(initialColor, "Prompt string" [, args]...); where: initialColor specifies the initial or default color for the color picker, as an RGB triple. "Prompt string" specifies the prompt string for the color picker. This string may contain printf-style format descriptors, which will be expanded using the succeeding arguments. args are optional arguments to be expanded into the prompt string. rgb receives the chosen color, as an RGB triple, or -1 if the user cancels the color picker. 1.4 The host application's current foreground and background colors are now available as RGB triples in the built-in variables fgColor and bgColor, respectively. 1.5 The individual components of an RGB triple or an RGBA quadruple may now be conveniently accessed with new built-in functions Rval, Gval, Bval, and Aval, which select the Red, Green, Blue, or Alpha components, respectively. The format for calling these functions is: r = Rval(rgbTriple); g = Gval(rgbTriple); b = Bval(rgbTriple); a = Aval(rgbaQuad); 1.6 Three new built-in functions allow your filter to play sound (.wav) files upon demand. The specified wave file name is first searched for in the filter's embedded resources. If not found among the resources, the wave file name is searched for in the local file system, using the customary search paths (see 2.9 below). Each function returns true if successful or false otherwise. Any waveform sounds that are played asynchronously will be automatically stopped when the filter exits. 1.6.1 To play a wave file asynchronously (i.e., the wave file starts playing and the function returns immediately, without waiting for the waveform sound to finish playing): success = playSoundWave("wavefilename.wav"); To stop any currently playing waveform sound, call this function with a NULL argument: success = playSoundWave(NULL); 1.6.2 To play a wave file synchronously (i.e., the function waits for the waveform sound to finish playing before returning): success = playSoundWaveSync("wavefilename.wav"); 1.6.3 To start playing a wave file repeatedly: success = playSoundWaveLoop("wavefilename.wav"); To stop a looping waveform sound: success = playSoundWave(NULL); 1.7 A new built-in string variable, filterInstallDir, will contain the full path name of the directory from which your filter was loaded (which is presumably the directory in which it was installed). This is useful for locating files (such as HTML help files) which were installed as separate resources in your filter's installation directory. (Note that at filter design time, filterInstallDir will contain the name of the directory from which FilterMeister itself was loaded, not the directory from which your target filter will ultimately be loaded at run-time.) 1.8 A new built-in function, shellExec(), lets your filter execute a Windows shell command. The calling format is: retcode = shellExec("Verb", "Filename", "Params", "DefDir"); where retcode will be -1 if successful, or an error code otherwise. "Verb" is the shell operation to be performed (e.g., "open", "print", or "explore"). "Filename" is the name of the file to be operated upon; it may be an executable file, a document file, or a URL. "Params" specifies any parameters to be passed to the application. "DefDir" specifies the default directory for the execution of the command. Any unneeded parameter may be set to NULL. If NULL is specified for "Verb", the function opens the file or URL specified by "Filename". For example, the following call will open file help.html from the filter's installation directory using the default web browser: shellExec("open", "help.html", NULL, filterInstallDir); 1.9 Four new built-in functions allow you to set and retrieve pixel values based on radial (polar) coordinates instead of rectangular (Cartesian) coordinates: pgetr(d, m, z) - returns the destination (output buffer) pixel value at angle d, distance m, from channel z (analogous to the pget(x,y,z) rectangular function) psetr(d, m, z, v) - sets the pixel value at angle d, distance m, in channel z of the destination (output) buffer to the clamped value of v, and returns this clamped value (analogous to the rectangular function pset(x,y,z,v)) tgetr(d, m, z) - returns the pixel value at angle d, distance m, from channel z of the first tile buffer (analogous to the tget(x,y,z) rectangular function) tsetr(d, m, z, v) - sets the pixel value at angle d, distance m, in channel z of the first tile buffer to the clamped value of v, and returns this clamped value (analogous to the rectangular function tset(x,y,z,v)) t2getr(d, m, z) - returns the pixel value at angle d, distance m, from channel z of the second tile buffer (analogous to the t2get(x,y,z) rectangular function) t2setr(d, m, z, v) - sets the pixel value at angle d, distance m, in channel z of the second tile buffer to the clamped value of v, and returns this clamped value (analogous to the rectangular function t2set(x,y,z,v)) Note that care must be exercised when using the *setr() functions, since there is no guarantee that they can be used to densely populate the plane; i.e., due to integer rounding of coordinates, etc., there may be points in the target buffer which cannot be addressed via integer polar coordinates (d,m). Thus, you may want to set the destination plane to all black (for example) before using the *setr() routines to cover any "holes" in the mapping. 1.10 Two new built-in functions allow you to efficiently apply gamma correction to an image: setGamma(g) - precomputes a gamma correction table for gamma value g, where g is a float or double value. (The gamma table is initially set to gamma = 1.0.) Returns true if successful, else false. gamma(i) - returns the gamma-corrected value of i, where 0 <= i <= 255. The result is undefined if i is out of range. Example: To copy the input buffer to the output buffer, applying a gamma correction of 1.8: setGamma(1.8); for (x = x_start; x < x_end; x++) for (y = y_start; y < y_end; y++) for (z = 0; z < 3; z++) pset(x, y, z, gamma(src(x, y, z))); 1.11 Three new event handlers have been added. 1.11.1 The OnFilterStart handler is invoked at the start of each filter run, just before the ForEveryTile, ForEveryPixel, and R/G/B/A handlers are called. The OnFilterStart handler is a good place to perform one-time calculations at the start of a filter run, check for valid control inputs, valid image mode, etc. The OnFilterStart handler should return false if filter processing is to continue with the ForEveryTile handler, or true to abort further filter processing (though this latter option is currently ignored in FM 0.4.14). 1.11.2 The OnFilterEnd handler is invoked at the end of each filter run, after all calls to the ForEveryTile, ForEveryPixel, and R/G/B/A handlers. The OnFilterEnd handler is a good place to perform any necessary cleanup at the end of a filter run, such as resetting the progress bar indicator. The OnFilterEnd handler should return false if the default OnFilterEnd handler code is to be invoked, or true to prevent the default handler from being invoked (though this latter option is currently ignored in FM 0.4.14). The default OnFilterEnd handler calls playSoundWave(NULL) to terminate any wave file that may still be playing. 1.11.3 The OnCtl(n) handler is invoked whenever the user clicks on or changes the value of a control. Within the OnCtl(n) handler, built-in variable n will be set to the index of the control which was activated, and built-in variable e will be set to one of the following symbolic constants to indicate the specific event that occurred: Symbolic Constant FM Event ----------------- ------------------------------------------ FME_UNKNOWN Unknown or unspecified event. FME_CLICKED Control was clicked (push buttons, etc.). FME_DBLCLK Control was double-clicked. FME_PAGEUP(*) Control was incremented by a large step (scrollbars, trackbars). FME_PAGEDOWN(*) Control was decremented by a large step (scrollbars, trackbars). FME_LINEUP(*) Control was incremented by a small step (scrollbars, trackbars). FME_LINEDOWN(*) Control was decremented by a small step (scrollbars, trackbars). FME_MOUSEOVER Mouse cursor entered the control window. FME_MOUSEOUT Mouse cursor exited the control window. (*) - These events are currently not processed by FM 0.4.14. The following FM event codes are also defined, but cannot occur as the value of e in the OnCtl(n) handler: FME_ZERODIVIDE An attempt was made to divide an integer by 0. FME_DIVIDEOVERFLOW Overflow occurred while trying to divide two integers. 1.12 A new built-in function doAction(a) performs one of several predefined control actions specified by its integer argument a, where a may have one of the following predefined symbolic constant values: Symbolic Constant Control Action ----------------- ------------------------------------------ CA_PREVIEW Updates the proxy preview window. CA_APPLY Applies the filter to the original source image and exits the plug-in. CA_CANCEL Exits the plug-in filter without modifying the original source image. CA_EDIT Enters or exits source code editing mode (ignored in standalone filters). CA_ABOUT Displays the ABOUT dialog box. CA_RESET Resets all controls to their initial values (not yet implemented in FM 0.4.14). CA_NONE Performs no action. 1.13 The following additional built-in (read-only) variables have been added to expose information provided by the host application. (Note that these values are guaranteed to be valid only when Adobe Photoshop is the host; other so-called Photoshop-compatible hosts may or may not provide useful information in these variables.) Variable Name Type Value ----------------- -------------- ------------------------------------- hostSerialNumber int The host application's serial number. Your plug-in filter can use this value as part of a copy-protection scheme. (Note: The Mac version of Photoshop apparently sets this field to a valid serial number, but on the Windows platforms Photoshop always sets this field to 0. Use the hostSerialString variable instead, which will be implemented in a later version of FM.) imageWidth int The source image’s width in pixels. If the selection is floating, this variable instead holds the width of the floating selection. imageHeight int The source image’s height in pixels. If the selection is floating, this variable instead holds the height of the floating selection. wholeWidth int The width in pixels of the entire source image, regardless of any floating selection. wholeHeight int The height in pixels of the entire source image, regardless of any floating selection. planes int For Photoshop 4+, this variable contains the total number of active planes in the image, including alpha channels. The image mode should be determined by looking at the imageMode variable. For earlier versions of Photoshop, this variable will be equal to 3 if filtering the RGB channel of an RGB color image, or 4 if filtering the CMYK channel of a CMYK color image. Otherwise it will be equal to 1. maxSpace int The maximum number of bytes of information the plug-in can expect to be able to access at once (input area size + output area size + mask area size + bufferSpace). isFloating bool This variable is true if and only if the selection is floating. haveMask bool This variable is true if and only if a non- rectangular area has been selected. bgColor int The current background color as a packed triple or quadruple in the color space native to the source image. Use the Rval, Gval, Bval, and Aval functions described in section 1.5 above to access the individual components of bgColor. fgColor int The current foreground color as a packed triple or quadruple in the color space native to the source image. Use the Rval, Gval, Bval, and Aval functions described in section 1.5 above to access the individual components of fgColor. hostSig int The host application provides its signature in this variable. Adobe Photoshop’s signature is '8BIM'. In theory, you can check for Photoshop as the host application with the following code; however, some other ill-behaved hosts also set hostSig to '8BIM'. if (hostSig == '8BIM') { // Host is Adobe Photoshop... } imageMode int The mode of the image being filtered, where Bitmap = 0, Gray Scale = 1, Indexed Color = 2, RGB Color = 3, CMYK Color = 4, HSL Color = 5, HSB Color = 6, Multichannel = 7, Duotone = 8, Lab Color = 9, 16-bit Gray Scale = 10, and 48-bit RGB Color = 11. filterCase int The type of data being filtered: Flat with no selection (1), Flat with a selection (2), Floating (3), Layer with editable transparency and no selection (4), Layer with editable transparency and a selection (5), Layer with preserved transparency and no selection (6), or Layer with preserved transparency and a selection (7). A zero indicates that the host did not set this variable, and the plug-in should look at the haveMask and isFloating variables to determine the filter case. samplingSupport int Indicates whether the host supports non-1:1 sampling for the proxy preview. 0 means no sampling support, 1 means integral sampling support, and 2 means fractional sampling support. Photoshop 3.0.1+ supports integral sampling steps; future versions may support non-integral sampling steps. 1.14 A new integer built-in variable, zoomFactor, has been added. This will contain a value between 1 and 16 to indicate the current zoom factor of the proxy preview window, or 0 if the proxy zoom factor has not yet been set. (In the current implementation, the zoomFactor variable is essentially the same as the built-in scaleFactor variable.) 1.15 Two new built-in functions, getCtlColor(c) and getCtlVal(c), have been added. getCtlColor(c) returns the current color of control c, as an RGB triple. getCtlVal(c) returns the current integer value of control c, and is simply a synonym for the ctl(c) function. 1.16 Two new built-in integer functions, HDBUsToPixels(n) and VDBUsToPixels(n), have been added. HDBUsToPixels converts horizontal DBUs (Dialog Box Units) to pixels; VDBUsToPixels converts vertical DBUs to pixels. The conversion factor depends on the current system font, and can be different in the horizontal and vertical directions. 2. Changes ---------- 2.1 The number of anonymous put/get cells has been increased from 256 to 1024. 2.2 The maximum number of local variables that the user can declare in a handler has been doubled from 200 to 400 (float and double variables count as two variables each). 2.3 The size of the compiler's semantic descriptor stack has been doubled, allowing the compilation of very complex expressions. Various code buffer sizes have also been increased to allow for the compilation of very long code sequences. If a code buffer nevertheless overflows, the name of the code buffer will now be identified in the overflow error message. Please report this buffer name when submitting a bug/performance report against FM. 2.4 Control values are now properly cached before the OnFilterStart handler is invoked. 2.5 Two alternatives to the built-in mix() function have been added, to handle rounding errors in different ways: mix1() and mix2(). The original mix() function retains its previous behavior for compatibility with Filter Factory. mix(a,b,n,d) is computed as a*n/d + b*(d-n)/d, per Filter Factory. mix1(a,b,n,d) is computed as (a*n + b*(d-n))/d, per Werner Streidt, to avoid some of the rounding errors inherent in the FF formula. mix2(a,b,n,d) is computed using a more complex formula to avoid other rounding errors that are introduced when (b - a)*n < 0. The bottom line: Experiment with mix, mix1, and mix2 to find out which version works best in your filter. When in doubt, mix1 is probably the best choice. 2.6 The size of the static text label associated with a standard scrollbar control is now dynamically adjusted to exactly fit the displayed text rather than using a fixed-size field. This should help eliminate some problems with truncation or overlap of label fields. Also, tooltips have been re-enabled for the static text label. 2.7 Setting the border style for a standard scrollbar control now sets the border style of the associated static text label. 2.8 The NOTIFY attribute has been implemented for button class controls. Setting this attribute allows the control to generate FME_DBLCLK events, which may then be processed by the OnCtl(n) handler. Note that an FME_DBLCLK event will always be preceded by an FME_CLICKED event for the same control. 2.9 FM now searches for a file in the following order when looking for a resource file such as a bitmap, icon, metafile, or sound wave file: 1. The current working directory is searched; 2. All directories listed in the PATH environment variable are searched; 3. All directories listed in the FM_PATH environment variable (if defined) are searched; 4. If the filename specifies an absolute pathname, that pathname is searched. 2.10 An error message is now issued when a case label (FM-E-ILLCASELAB) or a default label (FM-E-ILLDEFLAB) is found outside of any switch statement. 2.11 A warning is now issued (FM-I-IGNLAB) when a statement label is encountered, to warn that the label will be ignored. 2.12 Fatal "X86 Emit Error" message boxes during compilation now correctly abort the compilation when acknowledged, instead of trying to continue. 2.13 The CANCEL button in an "X86 Emit Warning" message box now correctly aborts the compilation. 2.14 FM now recognizes 'UP20' as the host signature for Megalux Ultimate Paint 2.0. 2.15 The host signature 'PSAd' is now reported as "Adobe Photoshop Adapter" instead of "ImageReady", since this signature is used by several Adobe products, not just ImageReady. 2.16 The body color of a scrollbar (STANDARD or SCROLLBAR) control can now be set with the color= property or the setCtlColor() function. 2.17 In Advanced editing mode, the following additional fields are now displayed in the Filter Parameter Block window if the Property Suite is available: propertyProcsVersion, numPropertyProcs, getPropertyProc, setPropertyProc If the getPropertyProc (or older getProperty) procedure is available, it is used to obtain and display the following additional information: propNumberOfChannels - Number of channels in the document. propCopyright - Whether the current image is considered copyrighted (1) or not (0). propInterpolationMethod - Current interpolation method: 1=point sample, 2=bilinear, 3=bicubic. propTitle - The title of the current image (usually its file name, or "Untitled-n" if not yet saved). propURL - The URL for the current image. propSerialString - Serial number of the plug-in host as a string. 2.18 The syntax for <color> can now include any integer expression; e.g., Dialog:color=100*256 will set the dialog background color to a dark green, and ctl[0]:fontcolor=fgColor will set the font color of control 0 to the currently selected foreground color. 2.19 The temporary tile buffers (tbuf and t2buf) are now set to the size of the input tile instead of the size of the output tile. 2.20 Several additional format descriptors are now recognized by the formatString() function and all other functions which implicitly call formatString: !h, !m, !O, !U, !w, and !z. The complete list of descriptors recognized by formatString is now: descriptor is replaced by ---------- ----------------------------------------------- !! "!" (i.e., a verbatim exclamation point) !A text specified by the Author key (filterAuthorText) !a text specified by the About key (filterAboutText) !C text specified by the Category key (filterCategoryText) !c text specified by the Copyright key (filterCopyrightText) !D text specified by the Description key (filterDescriptionText) !F text specified by the Filename key (filterFilenameText) !f the current Filter Case as a text string (filterCaseText) e.g., "Flat image, no selection" !H the name of the Host application (filterHostText) e.g., "Adobe Photoshop" !h the source image height as a decimal integer (imageHeight) !M the current Image Mode as a text string (filterImageModeText) e.g., "RGB Color" !m the current Image Mode as a decimal integer (imageMode) !O text specified by the Organization key (filterOrganizationText) !T text specified by the Title key (filterTitleText) !t text specified by the Title key, with any trailing ellipsis removed !U text specified by the URL key (filterURLText) !V text specified by the Version key (filterVersionText) !w the source image width as a decimal integer (imageWidth) !z the proxy zoom factor as a decimal integer (zoomFactor) 3. Bug Fixes ------------ 3.1 The built-in (val)?() function now works correctly when the control range is other than the default [0, 255]. 3.2 A setCtlText() redraw problem has been fixed for check box and radio button controls. 3.3 A bug which occurred when a switch statement had no default case has been fixed. 3.4 A problem which caused spurious error messages for 'short' and 'long' type specifiers has been fixed. 3.5 A bug which could cause a General Protection fault when the proxy preview was zoomed larger than the size of the preview window has been fixed. 3.6 A bug which caused incorrect code to be generated for Duff's device (and other cases in which a case label was nested within a loop statement enclosed by the corresponding switch statement) has been fixed. 3.7 A bug in the deletion of control fonts which could cause a crash on Windows NT has been fixed. 3.8 A problem which caused an incorrect syntax error message while looking for a specific character during compilation has been fixed. 3.9 A retry bug when tile buffer allocation failed has been fixed. 3.10 A workaround has been added for hosts such as PiCo (which uses imhost32.dll) and several others which expect the propertyLength field in the PiPL resource to always be a multiple of 4. 3.11 Several redundant stores to the Premiere-compatible variables i0, i1, u0, u1, v0, and v1 have been eliminated. 4. Known Problems ----------------- 4.1 The 'MaxBox' subkey in a Dialog specification is currently ignored. This fixes a problem in which the dialog box could be inadvertently maximized but not restored. 4.2 HDBUsToPixels() or VDBUsToPixels() can cause a divide error in USER.EXE if the result would be greater than approximately 32K pixels. This appears to be a limitation of the MapDialogRect Win32 API function. 4.3 Returning a value of true from the OnFilterStart handler does not abort the filter run as it should. 4.4 Returning a value of true from the OnFilterEnd handler does not cause the default OnFilterEnd processing to be skipped as it should. 4.5 The OnCtl(n) handler does not get invoked when a scrollbar or trackbar control is activated. |