30 - Plug-In Developer Documentation

 Note:

The very first thing you should do is contact us via email using redacted and request your free developer ID number (or range of numbers, if you need more than one to accommodate your design team.)

You need this information so you can put it in a special field in each plug-in you develop. The plug-in technology uses this (as well as revision, version and the plug-in's name) to maintain your plug-in's settings separately from all other plug-ins.

30.1 - General Concepts

F/x uses a new plug-in technology called Easy-Plug.

The name Easy-Plug is meant to be evocative of the idea that plug-ins for F/x actually are easy to create and use; and in fact, they are. Really!

We have gone the "extra mile" to ensure that as many issues as possible were addressed within F/x so that as you develop a plug-in, you can concentrate almost exclusively on working on the images - not on building dialogs, conducting interminable series of "handshakes" with the host program (F/x), or servicing all manner of peculiar event-driven happenings.

30.2 - Image File Import Plug-ins

Using the importer plug-in mechanism, you can create flat (atomic) bitmap loaders (or converters) for almost any imaginable image or data file type that can be automatically identified by your Importer by examining the file. You could convert vector types to bitmaps — even raw data files containing formatted numbers could be converted with a minimum of effort required as long as you used a dialog to interact with the user to make sure that the file being loaded is the correct one (but see the dire warning below about the pitfalls of greedily attempting to load poorly identified files with an Importer).

An Importer plug-in under F/x is a standard Windows DLL that is comprised of a very few (and very simple) "boilerplate" files that you should never have to deal with other than reading the header files (which are very informative) and as few as one (yes, one!) simple "c" file that contains three routines.

Importers are extremely simple; the example "imp_sstv128" developer example lays out all of the important ideas in just a few lines.

Basically, you write three functions as mentioned above.

The first function simply identifies the plug-in as to type, version, revision, developer number, file dialog description and wildcard:

"SSTV (*.pix),*.pix"

Type is a sub-field that is stored with the developer number that additionally marks this plug-in as an importer.

The second function is called when F/x wants to know if your plug-in thinks it can load the file in question. Your plug-in looks at the file, does whatever is required to identify the filetype as best as possible, and if your plug-in thinks it's the filetype it is intended to load, it returns:

  • The image size in pixels
  • A "confidence level" that reflects how sure it is it can load the file
  • An affirmative "yes I can load this file" response

At this point, when F/x sees the affirmative response, it will allocate an image for you that is of the specified x, y dimensions you provided, and your third function then attempts to actually load the file into that image.

If you are successful, you set additional information such as DPI or aspect ratio, alpha channel state, and if the format supplies it, author and/or copyright and/or annotation information. You then return, and the image is loaded.

If you are not successful, F/x will clean everything up and go on to the next importer or internal loader.

Importers have higher priority that F/x's internal loaders, so if you write an importer for an already supported format, you can handle it differently if you need to.

Only a few services are required for Importers, and in fact, only a few are guaranteed to be available. Morph, for instance, implements only those parts of the plugin system required to support importers. All services that are compatible with importers are so marked in the table at the end of this page.

 Tip:

One service that is particularly valuable for use with importers that are intended to process stream files (files with more than one image in them) running under F/x is SVC_TIMESTATE. This service can tell you if the timeline is running, what frame is currently being processed, and how many frames the timeline is set for. This can allow you to load particular files out of stream files. If the timeline is not running, or the service is not available (as in Moprh) you can intelligently bring up a dialog and ask the user which frame they would like to load.

That's all there is to it!

 Warning:

If the file type is one that cannot be identified with some reasonable degree of certainty then you should probably not attempt to write an importer for it. F/x depends upon the idea that files can be identified by the loader system, which includes the Importers you add.

If you write an Importer that takes over loading files it mistakenly identifies, the user will no longer be able to load those files correctly. This makes it absolutely imperative that your Importer's identification of it's files is done with as much accuracy as possible.

There is one way around this, and that is to open a dialog that interacts with the user during the file-type checking phase, requiring the user to confirm that they want your Importer to load that particular file. This is discouraged, however, because your Importer will ask this every time the user loads any file that the loader thinks (or dumbly assumes) the user might want to open it, which will annoy the heck out of the user, and probably cause them to toss your Importer into the trash!

30.3 - Image File Export Plug-ins

Image file export plug-ins are written using the Effects Plug-in mechanism which is described below. There are some special services you need to use, all of which are fully demonstrated in the "exp_sstv128" project.

Exporters may be dropped into the timeline underneath previous operations and they will automatically save the files with correct frame numbers appended as long as the file and path are correctly set in the plug-in dialog. They operate to export image file formats when the user clicks on a loaded image with any area selection tool, and (generally speaking) they would not be written to change the image, though you could change the image if there was a need to.

30.4 - Effects Plug-ins

Using the effects plug-in mechanism, you can create filters, apply to regions, follow strokes, manage images in different colors spaces, and much more - all with tons of user input, if that's appropriate for your plug-in.

An effects plug-in under F/x is a standard Windows DLL that is comprised of a very few (and very simple) "boilerplate" files that you should never have to deal with other than reading the header files (which are very informative) and as few as one (yes, one!) simple "c" file that contains these five routines:

identify()

This function sets up the name, version, revision and developer ID number for the plug-in and returns. No type is required to be added to the developer number, because the type of the effects plug-in is zero. Just four lines of "c" code will do it all:

// identify() // ----------------------------------- // Identify plugin to WinImages F/x // ----------------------------------- void identify(struct plug *p) { p->dev_key = 1; // 1=Black Belt Systems p->version = 1; p->revision = 0; strcpy(p->na,"Dr_Fill"); // name the plug-in }
initialize()

This function sets up the variables for your effect to a reasonable default. It is called when your plug-in is first installed. Extreme simplicity of use is again a hallmark. Here is an example from our dual range-fill sample plug-in:

void initialize(struct plug *p) { p->s[V_SWITCH1]=0; // not reversed p->s[V_SWITCH2]=1; // warping p->s[V_SWITCH3]=0; // not flipped p->r[V_RADIO4]=0; // horizontal // indicate we're initialized: p->init = 0; }
psetup()

This function sets flags to indicate the state of the dialog; it is called just prior to when F/x opens the dialog window. Here, you enable and label the various controls in the dialog. Typically, it will take three lines of "c" to do each control. A few more for radio buttons. Here's an example again from the dual range-fill sample plug-in:

void psetup(struct plug *p) { // palette one button p->enables[PL_CMD1]=1; p->refresh[PL_CMD1]=1; strcpy(p->labels[PL_CMD1],"Rng 1"); // palette two button p->enables[PL_CMD2]=1; p->refresh[PL_CMD2]=1; strcpy(p->labels[PL_CMD2],"Rng 2"); // reverse switch p->enables[PL_SWITCH1]=1; p->refresh[PL_SWITCH1]=1; strcpy(p->labels[PL_SWITCH1],"Reverse"); // warp switch p->enables[PL_SWITCH2]=1; p->refresh[PL_SWITCH2]=1; strcpy(p->labels[PL_SWITCH2],"Warp"); // flip switch p->enables[PL_SWITCH3]=1; p->refresh[PL_SWITCH3]=1; strcpy(p->labels[PL_SWITCH3],"Flip"); // Radio buttons for h and v modes p->enables[PL_RADIO4]=1; p->refresh[PL_RADIO4]=1; strcpy(p->labels[PL_RADIO4],"Mode"); strcpy(p->r4[0],"Horiz."); strcpy(p->r4[1],"Vert."); // we want an "about" button p->enables[PL_CMD30]=1; p->refresh[PL_CMD30]=1; strcpy(p->labels[PL_CMD30],"About..."); }
pchanged()

This function is called when the user changes something in your dialog. If one setting depends on another, or you want to ensure that certain values remain in a limited range, you handle that here. Very simple to handle, and done in a very standardized manner. In addition, if the user presses a "command button" you'll catch that here, and perform whatever is appropriate immediately. In addition to things like presetting values for "canned" effects, you can also call F/x "services" here — services such as edit your palettes, edit your profiles, edit a text file (or make a new one) and so on. Here's an example from our sample plug-in, Stripple:

void pchanged(struct plug *p) { long cmd; struct pkg package; // Variable Range Limiting: // ------------------------ if (p->l[V_LONG1] <= 0) // width must be at least one { p->l[V_LONG1] = 1; p->refresh[PL_LONG1] = 1; } if (p->l[V_LONG2] > p->l[V_LONG1]) // offset past width is undefined { p->l[V_LONG2] = p->l[V_LONG1]; p->refresh[PL_LONG2] = 1; } if (p->l[V_LONG3] > p->l[V_LONG1]) // offset past width is undefined { p->l[V_LONG3] = p->l[V_LONG1]; p->refresh[PL_LONG3] = 1; } // UI enable handling: // ------------------- if (p->enables[PL_RADIO5]) // if (radio 5 [h/v] is presently enabled) { if (p->s[V_SWITCH1]) // if (in stipple mode) { p->enables[PL_RADIO5]=0; // disable the UI element p->refresh[PL_RADIO5]=1; // request redraw } } else // radio 5 [h/v] presently disabled { if (p->s[V_SWITCH1]==0) // if (NOT in stipple mode) { p->enables[PL_RADIO5]=1; // enable the UI element p->refresh[PL_RADIO5]=1; // request redraw } } // Command Processing // ------------------ if ((cmd = p->bhit) != -1) { p->bhit=-1; // set back to no cmd present // "cmd" now contains the button (0 through 29) that was pressed. // Process appropriately. switch(cmd) { case V_CMD30: { strcpy(package.msg,"stripple.wip : " "created 2001.8.1\r\n" "Example for " "F/x Developers"); package.service = SVC_ABOUT; Svc(&package); break; } } } }
ex_function()

This is the function that does "your thing." It can be just a very few lines, or it can be as complex as you can imagine - it all depends on what you want your plug-in to do. The important idea is that all of the code in this function is devoted to working on the image using the variable parameters set by the user in the plug-in dialog - you have direct access to the image buffers (target, source, brush and undo) and you can work with the image data at the "metal" level, or, if you prefer, we have some very easy to use services that allow reading and writing of RGBA or HSLA data using an x-y paradigm. There are services to rescale images and more. Here's the execute section of our tint sample plug-in:

void ex_function(struct plug *p) { long x,y; unsigned char *mask; struct RGBa *rgba; struct pkg package,package2; if ((mask = p->msk) == NULL) return; // if (no mask) quit if ((rgba = p->ptgt.rgba) == NULL) return; // if (no image) quit package2.img = package.img = &p->ptgt; //point packages to image package.service = SVC_HSLr; // set read package2.service = SVC_HSLmw; //set write thru mask progressaset(p->na,p->my2-p->my1,1); // set up status bar - show progress for (y=p->my1; y<p->my2; y++) // for (every scan line in the selection) { if (progressupd(y)) // if (user aborts operation) { y=p->my2; // then [terminate loop normally, but early] } else // (not aborted) { package2.y=package.y=y; for (x=p->mx1; x<p->mx2; x++) // for (every column in the selection) { package2.x=package.x=x; Svc(&package); // read pixel package2.hslp.h = limit359(package.hslp.h + p->l[V_LONG1]); Svc(&package2); // write pixel } } } progressend(); // terminate the progress bar }

30.4.1 - Plugs

F/x maintains all the user variables for the effect. None are kept in local storage in your plug-in, everything is held within a structure called a "plug".

You can expose variables to the user by simply turning on the dialog element that corresponds to that element, or you can "hide" variables by simply not enabling the dialog.

There are 4 colors, 8 long integers, 8 floating points, 8 boolean switches, 5 multiple selection groups (an 8, two 4's and two 2's), and 2 strings.

If you elect to expose a variable, you simply enable and label the dialog element. If not, you just use it and F/x will maintain it. If it is not exposed, the user won't know it is there (except by the effect it has on your code, of course!)

Dialog elements that are not exposed have no label the user can see and are ghosted out.

 Note:

For further details on the plug structure, please see the example plug-ins and the plug_objects.h file. They are on the CD in the \source\plugins\ directory, and in the downloadable archive they show up at the same location where you extract the zip file.

30.4.2 - Services

Services are very easy to understand. There is a structure called a package that carries the variables you need for the various services. You set the variables, a service code, and call Svc() with a pointer to the package. Svc() will perform the service, and it may set variables in the package and return it to you. If the service fails, the service code will be set to zero. That's all there is to that.

 Note:

For details on the package structure, please see the example plug-ins and the plug_objects.h file. They are on the CD in the \source\plugins\ directory, and in the downloadable archive they show up at the same location where you extract the zip file.

The services themselves are documented in the plug_defines.h file; The formal documentation consists of which variables to set, what the service code is, and what the service does. You will also find that there is a sample plug-in supplied that implements every defined service type, so you can see how it is actually supposed to be done.

Further down the page (here), you will find a table with a brief definition of each service, as well as pointers to the specific example plug-ins we feel demonstrates the actual use of each service most clearly. We feel that as programmers, plug-in writers are best served by working examples they can imitate or modify.

30.4.3 - Masking

When the user (or the timeline) makes an area selection, F/x creates an 8-bit mask that represents the area selection on the action image. This mask will always be the same dimensions as the action image.

You may write "through" the mask, meaning that you can use it to control what you write to the image, or if you need to, you can write anywhere outside the mask. We provide services for both methods (in RGBA, HSVA and HSLA modes, a total of six services), and you can do both with direct buffer manipulation if you prefer to go that route. You can mix and match, too.

You can also request "stroke" information about the current area selection. This will result in a path that describes the user's mouse input in variable precision (you choose the precision you need, then we give you that description... see the "brushstroke" example to see how it works.) If you use a stroke to control writing, you should, by convention, use the "brush" image as the image data to transfer if you use image data at all for this purpose. Of course, you can choose to use the source image... or you could use both of them if you're really creative. We're just offering a little advice to keep the user feeling comfortable (when we suggest you use the brush image.)

If you use a stroke, you'll almost certainly be writing outside the supplied mask. For instance, if the user draws an ellipse with the ellipse tool, the mask will contain "on" pixels inside the ellipse... but when stroking, which is very like painting, you'd be following the edge, and unless your brush is only one pixel, you'll need to write outside the mask. Again, a great example of this is in the "brushstroke" sample plug-in.

Finally, you can elect to ignore the mask completely. Some operations are essentially "whole image" operations almost no matter how you look at them. That's ok too - the idea is just to provide the user with lots of functionality. F/x will update the whole image so that your changes will be visible. Also, if it turns out that you are writing to a layer of a layered image, the layer and the master image will be updated. You can write to a master image, but we re-create them on the fly so your changes will never persist. That's the same way "normal" operators work within F/x, by the way.

30.4.4 - Image Resampling

This is one of the services ("SVC_RESAMPLE"). F/x provides you with a new image, made from an image you supply, resampled to the specified x and y values. The important thing to note here is that you can either use another service ("SVC_DISPOSE") to free the image, or, if you don't free it yourself, F/x will free it, and any other images allocated during the execution of your plug-in, automatically. You must decide how to manage memory in such a way that it is most efficient; if you'll be getting multiple images, then you should probably be using "SVC_DISPOSE". If you're only getting one, then it can be ok to let F/x get rid of it for you. This automatic disposal is always effective, you don't have to turn it on or off.

Memory allocation works this way too - see this documentation for details.

 Tip:

Resampling works best in factors of down to 1/2 or up as far as you like. For the best results, you may want to resample in stages if you're going to be going further in the smaller direction.

For instance, if you were going from 500 pixels to 250 pixels, that's 1/2 and is ok. But if you were going from 500 to 100 pixels, doing three resamples: 500 to 250, then 250 to 125, and then 125 to 100 would get you a truer result.

What do we mean by "truer"? (Warning: this gets technical.) When producing a resampled output, F/x produces a perfect linear interpolation between the two pixels that comprise the neigbors of the fractional downsampled or upsampled location in the new image for each axis. From .5 on up, those neighbors are the pixels closest to the resampled output. Beyond those ranges, the neighbors may be located one or more pixels away, and so the interpolated lcoations can skip the nearest neighbors. By doing the interpolation in stages, you can ensure that all pixels are accounted for in the output result. This (of course) takes longer to perform, but F/x's resampling code is extremely quick, so it's not too painful. In addition to improving the veracity of the image, there will be less chance of aliasing on high-frequency image content if you take the multiple-pass approach.

If one axis is to be resampled to a level where you determine you want to do multiple passes, but the other can be done in fewer, then for the first few passes, simply specify the same output resolution as input and no resampling will occur on that axis. Then, on the later pass or passes, perform the resample on the axis that still requires it. Here's an example, from 500x100 to 100x50:

PassInputOutput
pass 1500x100250x100
pass 2250x100125x100
pass 3125x100100x50

Speaking from a purely perceptual viewpoint, when you resample in multiple stages, reduced size image pixels will appear softer, as more image data becomes represented in each pixel. If you take the one-pass approach, there can be a perceptual sharpening by comparison in some cases. The latter positive side-effect is compromised, sometimes severly, by subsample level aliasing effects.

30.4.5 - Obtaining a new image

The "SVC_NEWIMAGE" service will get you a pointer to a new image. This image is for your plug-in to work with. It does not reveal itself to the user of F/x. When your plug-in returns to control to F/x, any image obtained with "SVC_NEWIMAGE" will automatically be deleted, unless you have used "SVC_DISPOSE" to get rid of it yourself, first. You can obtain as many images as there is memory available for.

30.4.6 - Plug-In life (scope)

Plug-ins are invoked by F/x as a DLL. A structure called a plug is passed to the DLL, and in this structure are all the variables that have a life that exceeds the invocation of the DLL.

The DLL itself must be stateless; all actions taken depend only upon the variables in the plug structure.

F/x will maintain the variables in the plug not only between invocations of your plug-in in one session, but over multiple sessions (if the user has the appropriate preferences flag checked, which is the default.)

30.4.7 - User-accessible Variables

All variables, as mentioned previously, are in the plug structure. Each variable is in an array of that type; 8 longs, 8 switches, 5 longs for the radio buttons and so forth. For instance, you could access the third switch this way, where p is a pointer to the plug structure:

x = p->s[V_SWITCH3];

This is consistent throughout plug-in design.

30.4.8 - User Interface Handling

There are basically two user interface issues for each element of the plug-in.

First, is the user interface element enabled; and secondly, do you wish F/x to refresh that element (you want this when you change the enable state or the value of the variable.)

30.4.9 - Memory

Within the environment of the plug-in we have provided very high speed memory allocate and deallocate calls named "alloc_mum()" and "free_mum()". You may get an unlimited number of memory chunks and are unrestrained in chunk size with these calls (excepting of course any limitations that are inherent with 32-bit Windows.) You should definitely use these instead of malloc(), free() and their siblings. Why? Because F/x keeps track of all memory allocated and freed using these calls and when your plug-in terminates, F/x will automatically clean up any remaining memory. Not that you would ever leave memory unfreed, of course, that would be someone else, but you should do it in case one of those reckless types ever sees your code. You do want to be a good example, don't you?

Images work the same way. See this documentation.

30.4.10 - Caveats

Some simple (and probably obvious) advice:

  • Don't specify service positions outside the image xw,yw bounds
  • Don't overwrite boundaries of arrays in "plugs" or "packages"
  • Don't give your plug-in any other extension than ".WIP"
  • Don't use "malloc()" or "calloc()"
  • Do use "alloc_mum()" and "free_mum()"
  • Do make sure you fill in all the fields of any service you call
  • (the services do not validate the fields in order to obtain maximum speed... feed them bad data, and you'll probably crash.)

30.4.11 - Creating new Plug-Ins from the Examples

Here is how to create a new plug-in, hypothetically entitled "clean_up", from an example plug-in (we'll use "de_white" as an example here, but you should use any one you like.)

  • Using Explorer, duplicate the supplied plug-in directory "de_white" (and all its contents), and then re-name the directory to the name of your new plug-in "clean_up".

     Warning:

    We strongly suggest you use only letters, numbers and the underscore for all names and filenames in these projects. Although Microsoft® and Apple® both apparently support directories and filenames that contain spaces and various unusual non-alphanumeric characters, this support is spotty and unreliable, especially in the case of Microsoft®. Under the command shell in Windows, for instance, a filename with spaces must be quoted to work properly (and that doesn't even always work.) Other operating systems may not support spaces in filenames at all, and some applications may not support them even if the host "OS" claims to.

    If you want to separate names inside one filename, use an underscore (the underline character, usually next to the zero key at the top of the keyboard.)

    Use "clean_up" not "clean up"

    Technically speaking, spaces in filenames are a very bad idea for many reasons, and we discourage you from using them in the very strongest terms.

  • Open Visual Studio, and use File/Open Workspace to open the ".DSW" file you'll find in the newly created directory, "clean_up".

  • Within Visual Studio on the FileView pane, all the example plug-ins have one obvious C file in the folder "c_source" that contains the code specific to that particular example. For example, for the de_white plug-in, that file is "de_white.c". Load the "de_white.c" file by double-clicking on it in the FileView pane, then use the Save As command from the File menu to save it with an appropriate new filename for your plug-in, "clean_up.c".

  • DELETE the original file from the project by left-clicking on it in the FileView pane and subsequently pressing the DEL key on your keyboard.

  • Right-click on the File Editing pane and select Insert File into Project from the context menu. The file will now appear at the end of the File View pane. Drag it from the end, into the "c_source" folder.

  • In the File View pane, open the "linker_esoterica" folder, and double-click on the ".DEF" file to open it. It will appear in the File Editing pane. Change the LIBRARY statement to the name of the new plugin, eg "clean_up".

  • Select the menu command Project / Settings. You will observe a drop-down list entitled Settings For at the top left of the dialog that opens. Set it to "RELEASE".

  • Under the Link tab, there is a field entitled "Output file name:". Change the output filename (and path, if you need to) so that the linker output will create "clean_up.wip" in the directory where you will be keeping plugins for F/x.

  • With this same dialog still open, the same drop-down list entitled at the top left of the dialog must now be set to "DEBUG". Now, repeat the changes in the previous step in the Link tab for the "DEBUG" "Output file name:" field. Close the dialog.

At this point, you should have a new plug-in with the name "clean_up". You may now proceed to code your plug-in by changing the "clean_up.c" file as required, and adding new functions and files as you need them.

30.4.12 - Examples

There are a number of examples of various types of plug-ins in the \source\plugins\ directory. Each example, and the header files, have comments that should help you a great deal in understanding what is going on. If you have further questions, please direct them to redacted

...but we bet you won't have many!

 Note:

All services are available to effects plug-ins. However, a more limited set of services is available to importers - many services make no sense in the context of importing a file.

All services that are available to importers are marked like this:

Service is available to Importers

Here's where to look for examples and information on various important plug-in subjects:

IssueLearn about it here:
Allocating Memory"dr_fill" example. See also this documentation
Locating vertexes placed by linear area tools"plop" example and "plug_objects.h"
Automatic image freeingImplicit. See this documentation
Automatic memory freeingImplicit. See this documentation
Brush image handling"brushstroke" example
Checkmark UI elements (switches)"dr_fill" example
Command Button UI elements"dr_fill" example
Color Well UI elements"stripple" example
Direct pixel buffer access"colorfill" example
Enabling UI elements in generalMost examples
Error Message Production"cglass" example
Floating point UI elements"de_white" example
"pchanged()" functionAll examples
"ex_function()" functionAll examples
"psetup()" functionAll examples
"identify()" functionAll examples
"initialize()" functionAll examples
Freeing memory"dr_fill" example. See also this documentation
"HSLA" structure"tint" example and "plug_objects.h"
Integer UI element"stripple" example
Labeling UI objectsMost examples
Direct use of the area selection mask"de_white" example
Endpoints of linear mode area selections used as markers"plop" example and "plug_objects.h"
Numeric Error Messages sent to the user"blur" example
General Messages sent to the user"blur" example
"palette" structure"dr_fill" example and "spalette.h"
"pkg" (package) structureMany examples and "plug_objects.h"
"plug" structureAll examples and "plug_objects.h"
"proffer" (profile) structure"remap" example and "spalette.h"
Abortable progress bar updatingMost examples
Setting up the progress barMost examples
"pu_image" structureMost examples and "plug_objects.h"
Radio button UI elements"stripple" example
Refresh UI ElementsMost examples
"RGBa" structure"merge" example and "plug_objects.h"
Source Image handling"merge" example
String UI elements"" example
"SVC_ABOUT" service
(putting up an "About" dialog)
All examples and "plug_defines.h"
"SVC_DODIALOG" service
(putting up an informational dialog)
Service is available to Importers
"edit" example and "plug_defines.h"
"SVC_ALPHASTATE" service
(change an image's "hasalpha" state)
"de_white" example and "plug_defines.h"
"SVC_DISPOSE" service
(freeing images you allocate)
Service is available to Importers
"merge" example and "plug_defines.h"
"SVC_DISPr" service
(Read a vector displacement from a warp layer)
"cglass" example and "plug_defines.h"
"SVC_DISPw" service
(Write a vector displacement to a warp layer)
"cglass" example and "plug_defines.h"
"SVC_EDITpal" service
(edit one of the two palettes)
"dr_fill" example and "plug_defines.h"
"SVC_EDITpro" service
(edit one of the 12 profiles)
"remap" example and "plug_defines.h"
"SVC_EDITtxt" service
(edit a text file, new or previously existing)
"edit" example and "plug_defines.h"
"SVC_GETSAMPLE" service
(retrieve the RGB and Alpha samples from F/x)
"re_alpha" example and "plug_defines.h"
"SVC_HSL2RGB" service
(convert HSLA to RGBA data)

Service is available to Importers|"tint2" example and "plug_defines.h"
"SVC_HSV2RGB" service
(convert HSVA to RGBA data)
Service is available to Importers
"tint2" example and "plug_defines.h"
Note that the example uses HSL and not HSV; however, change the functions from HSL to HSV and you're good to go.
"SVC_HSLmw" service
(write HSLA data through the selection mask)
Service is available to Importers
Mask ignored in importers
"tint" example and "plug_defines.h"
"SVC_HSLr" service
(read HSLA data from the image)
Service is available to Importers
"tint" example and "plug_defines.h"
"SVC_HSLw" service
(write HSLA data to the image ignoring the selection mask)
"tint2" example and "plug_defines.h"
"SVC_HSVmw" service
(write HSVA data through the selection mask)
Service is available to Importers
Mask ignored in importers
"tint" example and "plug_defines.h"
Note that the example uses HSL and not HSV; however, change the functions from HSL to HSV and you're good to go.
"SVC_HSVr" service
(read HSVA data from the image)
Service is available to Importers
"tint" example and "plug_defines.h"
Note that the example uses HSL and not HSV; however, change the functions from HSL to HSV and you're good to go.
"SVC_HSVw" service
(write HSVA data to the image ignoring the selection mask)
Service is available to Importers
"tint2" example and "plug_defines.h"
Note that the example uses HSL and not HSV; however, change the functions from HSL to HSV and you're good to go.
"SVC_RESAMPLE" service
(obtain a new image in a new size, made from an image you supply)
"merge" example and "plug_defines.h"
See also this documentation
"SVC_NEWIMAGE" service
(obtain a new image in a new size)
Service is available to Importers
"plug_defines.h" See also this documentation
"SVC_RESET" service
(Set all plug-in parameters back to defaults)
"stripple" example and "plug_defines.h"
"SVC_RGB2HSL" service
(convert RGBA data to HSLA data)
Service is available to Importers
"tint2" example and "plug_defines.h"
"SVC_RGB2HSV" service
(convert RGBA data to HSVA data)
Service is available to Importers
"tint2" example and "plug_defines.h"
Note that the example uses HSL and not HSV; however, change the functions from HSL to HSV and you're good to go.
"SVC_QUERYMASK" service
(ask if selection mask specifies placement at x,y)
"dr_fill example" example and "plug_defines.h"
"SVC_RGBmw" service
(write RGBA data to an image through the selection mask)
Service is available to Importers
Mask ignored in importers
"merge example" example and "plug_defines.h"
"SVC_RGBr" service
(read RGBA data from an image)
Service is available to Importers
"merge example" example and "plug_defines.h"
"SVC_RGBFr" service
(read fractional RGBA data from an image)
"merge example" example and "plug_defines.h"
"SVC_GETVERSION" service
(Get software's version, revision and level)
Service is available to Importers
"edit example" example and "plug_defines.h"
"SVC_SETPTM" service
(Set pixel transfer mode)
"plug_defines.h"
"SVC_RGBw" service
(write RGBA data to an image, ignoring the selection mask)
Service is available to Importers
"de_white" example and "plug_defines.h"
"SVC_STROKE" service
(obtain a record of a specific number of co-ordinates along the stroke path a user made)
"brushstroke" example and "plug_defines.h"
"SVC_STROKELEN" service
(determine how long, in pixels, a stroke was)
"brushstroke" example and "plug_defines.h"
"SVC_SETAUTHOR" service
(set author information to MSG text string)
Service is available to Importers
"imp_sstv128" example and "plug_defines.h"
"SVC_SETDPI" service
(set image DPI information to x and y variables)
"plug_defines.h"
"SVC_SETANNO" service
(set annotation information to MSG text string)
Service is available to Importers
"imp_sstv128" example and "plug_defines.h"
"SVC_SETCOPYRIGHT" service
(set copyright information to MSG text string)
Service is available to Importers
"imp_sstv128" example and "plug_defines.h"
"SVC_GETAUTHOR" service
(get image author information to MSG text string)
"plug_defines.h"
"SVC_GETANNO" service
(get image annotation information to MSG text string)
"plug_defines.h"
"SVC_GETCOPYRIGHT" service
(get image copyright information to MSG text string)
"plug_defines.h"
"SVC_GETFEXISTS" service
(find out if need to warn user when file being saved already exists)
"exp_sstv128" example and "plug_defines.h"
"SVC_TIMESTATE" service
(determine if operating in timeline, and framing issues)
"exp_sstv128" example and "plug_defines.h"
"SVC_GAUSSBLUR" service
(Perform gaussian blur of img in package)
"plug_defines.h"
"SVC_MASKCHANGED" service
(make F/x recalculate mask prior to use)
"plug_defines.h"
"SVC_PUSHMASK" service
(Save mask on mask stack)
"plug_defines.h"
"SVC_POPMASK" service
(Retreive mask from stack)
"plug_defines.h"
"SVC_DELMASK" service
(Delete mask from stack)
"plug_defines.h"
"SVC_EXGMASK" service
(Exchange mask with mask on top of stack)
"plug_defines.h"
"SVC_HARDFEATHRRMASK" service
(All nonzero mask elements become 255)
"plug_defines.h"
"SVC_NOFEATHERMASK" service
(All non-255 mask elements become 0)
"plug_defines.h"
"SVC_FEATHERMASK" service
(Feather mask from 0.1 to 20.0 pixels)
"plug_defines.h"
"SVC_SETMASK" service
(Set entire mask to value)
"plug_defines.h"
"SVC_SETSEL" service
(Set selected region of mask to value)
"plug_defines.h"
"SVC_INVERTMASK" service
(Invert (255-v) all mask values)
"plug_defines.h"
"SVC_INVERTSEL" service
(Invert (255-v) all mask elements within the selection)
"plug_defines.h"
"SVC_SCOMBINEMASK" service
(Combine mask with top of stack. Top of stack not affected, results are lowest (most unselected) of the two masks in, placed in mask itself.)
"plug_defines.h"
File Exporter plug-in"exp_sstv128" example
File Importer plug-in"imp_sstv128" example
Using the Windows "MessageBox()" function in a plug-in"exp_sstv128" example
Using the Windows "Browse for Folder" function in a plug-in"exp_sstv128" example
Undo image handling"blur" example
Variable range limiting"stripple" example
User interface handlingMost examples
Keyboard Navigation
, Previous Page . Next Page t TOC i Index o Operators g Glossary
WinImages F/x, Morph and all associated documentation
Copyright © 1992-2007 Black Belt Systems ALL RIGHTS RESERVED Under the Pan-American Conventions
WinImages F/x Manual Version 7, Revision 6, Level A

Valid HTML 4.01 Loose
 

This manual was generated with wtfm
wtfm uses aa_macro and SqLite
aa_macro uses python 2.7
Page 412