PARASITE REGISTRY - 1999-05-31 ================= This document is designed for the convenience of GIMP developers. It does not need to concern users. >>>> If your plugin or script writes parasites, please >>>> amend this file in CVS or submit patches to >>>> gimp-developer@scam.xcf.berkeley.edu ------------------------------------------------------------------ *** NAMESPACE Plug-in-specific data should be prefixed by the plug-in function name and a slash, i.e. private data of plug_in_displace should be named like: plug_in_displace/data1 plug_in_displace/data2 etc. Global data follows no strict rules. ------------------------------------------------------------------ *** KNOWN PREFIXES: "tiff" : The standard GIMP TIFF plugin "jpeg" : The standard GIMP JPEG plugin "gimp" : For common and standard parasites ------------------------------------------------------------------ *** KNOWN PARASITES: "gimp-comment" (IMAGE, PERSISTENT) Standard GIF-style image comments. This parasite should be human-readable text, preferably in utf8 encoding. A trailing \0 might be included and is not part of the comment. "tiff-save-options" (IMAGE) The TiffSaveVals structure from the TIFF plugin. "jpeg-save-options" (IMAGE) The JpegSaveVals structure from the JPEG plugin. "/_fu_data" (GLOBAL, IMAGE, DRAWABLE, PERSISTENT) The Gimp::Fu module might store the arguments of the last plug-in invocation. It is usually attached to images, but might also be found globally. The data format is either pure character data (Data::Dumper) or a serialized data stream created by Storable::nfreeze. ------------------------------------------------------------------ *** PARASITE FORMAT: The parasite data format is not rigidly specified. For non-persistant parasites you are entirely free, as the parasite data does not survive the current gimp session. If you need persistant data, you basically have to choose between the following alternatives (also, having some standard for non-persistant data might be fine as well): - cook your own binary data format You can invent your own data format. This means that you will either loose totally (consider endian-ness or version-ness issues) or you will get yourself into deep trouble to get it "right" in all cases. - use character (string) data Obvious to perl people but less so to C programmers: just sprintf your data into a string (e.g. "SIZE 100x200 XRES 300 YRES 300") and store that in the parasite, and later sscanf it again. This often solves most of the problems you might encounter, makes for easier debugging and more robustness (consider the case when you add more entries to your persistant data: older plug-ins might be able to read the relevant parts and your application can detect missing fields easily). The drawback is that your data is likely to be larger than a compact binary representation would be. Not much a problem for most applications, though. You could also use one parasite per field you store, i.e. foo-size, foo-offset-x, foo-offset-y etc... - use the libgimp serialize functions Look at the stuff in libgimp/gserialize.h. These functions allow for relatively easy serializing/deserializing of structs. The advantages are that the gimp-developers have already taken care of endian-ness issues and other hazzles. The drawback is that you might encounter problems when you want to extend your structures later, as you have to be prepared for images saved with parasites form a very old version of your plug-in, and the gserialize functions do not handle different data formats nicely itself. One way out around this is to prefix your data with a version identifier (remember to use a guchar, i.e. something without endian-ness problems). Remember to skip it before deserializing. Another very easy way is to add a version tag to your parasite name, i.e. "foo-bar-v1", "foo-bar-v2". Your plug-in could then check for older versions and act accordingly and/or attach the new parasite or both the new and the old version of your data. The gserialize stuff also makes it possible to just append more fields (i.e. more gserialized structs) to your data. You could check the length of the parasite data ("anything left?") to decide wether to decode more fields. Here's some example: data = parasite_data(p); size = parasite_data_size(p); length = gdeserialize(...); tlength += length; data += length; if (tlength != size) gdeserialize the next one, etc.