
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 in UTF-8 encoding.  A trailing \0 might
        be included and is not part of the comment.

"gimp-brush-pipe-parameters" (IMAGE, PERSISTENT)
	This is all very preliminary:

	A string, containing parameters describing how an brush pipe
	should be used. The contents is a space-separated list of
	keywords and values. The keyword and value are separated by a
	colon.

	This parasite is currently attached to an image by the psp
	plug-in when it loads a .tub file (Paint Shop Pro picture
	tube). It is used (first attached with values asked from the
	user, if nonexistent) by the gpb plug-in when it saves a .gih
	file. The .gih file contains the same text in it.

	The keywords are:
	ncells: the number of brushes in the brush pipe
	step: the default spacing for the pipe
	dim: the dimension of the pipe. The number of cells
		in the pipe should be equal to the product
		of the ranks of each dimension.
	cols: number of columns in each layer of the image,
		to be used when editing the pipe as a GIMP image
	rows: ditto for rows. Note that the number of columns and rows
		not necessarily are identical to the ranks of the
		dimensions of a pipe, but in the case of two-
		and three-dimensional pipes, it probably is.
	rank0, rank1, ...: (one for each dimension): the index range
		for that dimension
	placement: "default", "constant" or "random". "constant" means
		use the spacing in the first brush in the pipe.
		"random" means perturb that with some suitable
		random number function. (Hmm, would it be overdoing it
		if the pipe also could specify what random function
		and its parameters...?)
	sel0, sel1, ...: "default", "random", "incremental", "angular",
		"pressure", "velocity", and whatever else suitable we might
		think of ;-) Determines how one index from each dimension is
		selected (until we have pinpointed the brush to use).

"tiff-save-options" (IMAGE)
        The TiffSaveVals structure from the TIFF plugin.

"jpeg-save-options" (IMAGE)
        The JpegSaveVals structure from the JPEG plugin.

"gamma" (IMAGE, PERSISTENT)
	The original gamma this image was created/saved. For JPEG; this is
        always one, for PNG it's usually taken from the image data. The gimp
        might use and modify this. The format is an ascii string with the
        gamma exponent as a flotingpoint value.

        Example: for sRGB images this might contain "0.45454545"

"chromaticity" (IMAGE, PERSISTENT)
	This parasite contains 8 floatingpoint values (ascii, seperated by
        whitespace) specifying the x and y coordinates of the whitepoint, the
        red, green and blue primaries, in this order.

        Example: for sRGB images this might contain
        "0.3127 0.329 0.64 0.33 0.3 0.6 0.15 0.06"
         wx     wy    rx   ry   gx  gy  bx   by
 
"rendering-intent" (IMAGE, PERSISTENT)
	This specifies the rendering intent of the image. It's a value
        between 0 and 3, again in ascii:

        0 - perceptual			(e.g. for photographs)
        1 - relative colorimetric	(e.g. for logos)
        2 - saturation-preserving	(e.g. for business charts)
        3 - absolute colorimetric

"<plug-in>/_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.

"hot-spot" (IMAGE, PERSISTENT)
	Use this parasite to store an image's "hot spot". Currently
	used by the XBM plugin to store mouse cursor hot spots.

	Example: a hot spot at coordinates (5,5) is stored as "5 5"

"icc-profile" (IMAGE, PERSISTENT)
	This contains an ICC profile describing the color space the
	image was produced in. TIFF images stored in PhotoShop do 
	oftentimes contain embedded profiles. An experimental color
	manager exists to use this parasite, and it will be used
	for interchange between TIFF and PNG (identical profiles)


------------------------------------------------------------------

*** 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

  NOTE: libgimp/gserialize.[ch] has been excluded from the build since
        gimp-1.2. This decision was made since noone seemed to use it so
        far. The files can still be pulled out of CVS, so if you decide
        to use them, you will have to include a copy into your plugin
        source or resurrect the functionality in libgimp.

  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.
