Quick Nav Bar | ||||||||
---|---|---|---|---|---|---|---|---|
<< Previous | Contents |
Selection |
Op Index |
Parent | User Notes |
Index |
Glossary |
Next >> |
|
The name Easy-Plug is meant to be evocative of the idea that plug-ins for WinImages 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 WinImages 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 (WinImages F/x), or servicing all manner of peculiar event-driven happenings.
An Importer plug-in under WinImages 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:
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 WinImages 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:
At this point, when WinImages 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, WinImages F/x will clean everything up and go on to the next importer or internal loader.
Importers have higher priority that WinImages 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.
|
That's all there is to it!
|
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.
An effects plug-in under WinImages 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()
|
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)
// indicate we're initialized:
| |
This function sets flags to indicate the state of the dialog; it is called just prior to when WinImages 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 two button
// reverse switch
// warp switch
// flip switch
// Radio buttons for h and v modes
// we want an "about" button | |
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 WinImages 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)
// Variable Range Limiting:
if (p->l[V_LONG2] > p->l[V_LONG1]) // offset past width is undefined
if (p->l[V_LONG3] > p->l[V_LONG1]) // offset past width is undefined
// UI enable handling:
// Command Processing
// "cmd" now contains the button (0 through 29) that was pressed. Process appropriately.
| |
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) |
Plugs
WinImages 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 WinImages 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.
|
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
|
Masking
When the user (or the timeline) makes an area selection, WinImages 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. WinImages 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 WinImages F/x, by the way.
Image Resampling
This is one of the services ("SVC_RESAMPLE"). WinImages 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, WinImages 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 WinImages 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.
|
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 WinImages F/x. When your plug-in returns to control to WinImages 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.
Plug-In life (scope)
Plug-ins are invoked by WinImages 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.
WinImages 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.)
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.
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 WinImages F/x to refresh that element (you want this when you change the enable state or the value of the variable.)
Memory
Within the environment of the plug-in we have provided very high speed memory allocate and deallocate calls named "
Images work the same way. See this documentation.
Caveats
Some simple (and probably obvious) advice:
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.)
|
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.
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 support@blackbeltsystems.com
...but we bet you won't have many!
|
Here's where to look for examples and information on various important plug-in subjects:
Issue | Learn 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 freeing | Implicit. See this documentation |
Automatic memory freeing | Implicit. 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 general | Most examples |
Error Message Production | "cglass" example |
Floating point UI elements | "de_white" example |
" |
All examples |
" |
All examples |
" |
All examples |
" |
All examples |
" |
All examples |
Freeing memory | "dr_fill" example. See also this documentation |
" |
"tint" example and "plug_objects.h" |
Integer UI element | "stripple" example |
Labeling UI objects | Most 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) structure | Many examples and "plug_objects.h" |
"plug" structure | All examples and "plug_objects.h" |
"proffer" (profile) structure | "remap" example and "spalette.h" |
Abortable progress bar updating | Most examples |
Setting up the progress bar | Most examples |
"pu_image" structure | Most examples and "plug_objects.h" |
Radio button UI elements | "stripple" example |
Refresh UI Elements | Most 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 WinImages 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 save 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 WinImages 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 handling | Most examples |
Quick Nav Bar | ||||||||
---|---|---|---|---|---|---|---|---|
<< Previous | Contents |
Selection |
Op Index |
Parent | User Notes |
Index |
Glossary |
Next >> |
WinImages F/x Manual Version 7, Revision 5, Level B |