www.delorie.com/gnu/docs/xaos/xaos_24.html   search  
 
Buy GNU books!


An fast realtime interactive fractal zoomer

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.3.2 Initialization

During initialization phaste each filter says to his parrent what kind of images it supports (this should depend on images supported by his child), parent chooses best supported image format for his purposes and gives it to the child. Initialization is done in two pases.

First pass start by lowest filter in the queue and each filter passes to his parrents requirement structure.

Second pass starts by the highest filter and each filter passes to child an image and some other stuff. Then caluclation should begin.

Queue needs to be reinicialized after creating, resizing, adding/removing of filter and similiar operations.

First pass is implemented using require function. This function is expected to take care at child's requirements it received as parameter, fill requirements structure and call require function of his parent filter.
 
struct requirements {
  int nimages;
  int supportedmask;
  int flags;
};
The nimages field should be set to 1 or 2. In case it is 2, parent filter must pass image with two buffers. Note that in case it is 1, parent should pass image with two buffers too.

Supported mask is mask of supported image types by filter. Image types are following:

C256
An normal 8bpp image with palette
REALCOLOR
An 16bpp image with 5 bits for red, 5 bits for green and 5 bits for blue
HICOLOR
An 16bpp image but with 6 bits for green
TRUECOLOR24
An 24bpp truecolor image with 8bits for each color.
TRUECOLOR
An 32bpp truecolor image with 8bits for each color.
LARGEITER
An 16bpp image but w/o colors. It is expected to hold number of iterations it should be also tought as 16bpp grayscale image
SMALLITER
Similiar to LARGEITER but 8bpp

In case you don't wory about palettes, allocations of colors and you do just some operation with bitmap, so you wory just abour depth of image you should use mask of following: MASK1BPP for 8 bit images, MASK2BPP for 16bit and so on.

The latest field of requirements structure is flags. It mask from following constants:

IMAGEDATA
in case your filter requires data from previous frame untouched. In case this is not set, filters should reuse your image and change it. But some filters like and motion blur or zooming engine requires data from previous frame to construct new, so this flag should be set
there is no more flags supported at the moment. Function require should also save child's require structure into filter->req for later use by initialize pass. So you should look like:
 
static int requirement(struct filter *f,struct requirements *r)
{
  f->req=*r;    /*Save an child's requirements*/
  r->nimages=1; /*Just one image is required*/
  r->flags&=~IMAGEDATA;/*unset the imagedata field*/
  r->supportedmask=C256|TRUECOLOR|HICOLOR|REALCOLOR;
                /*mask of all supported image types*/
  return (f->next->action->requirement(f->next, r));
                /*call parent*/
}
Next pass is main initialization. It goes in oposite order(from parent to child) and child's inhers some stuff from parent like images etc... The initialize structure receives an initdata structure:
 
struct initdata {
  void (*wait_function) (struct filter *f);
  struct image *image;
  struct fractal_context *fractalc;
  int flags;
};
an wait_function is function called by filter during calculation that lets the parent filters(usually user interface layer) to inform user how calculation continues. Image is an image expected to be filled by image in calculation phaste. Fractalc is pointer to structure that will contain information about fractal during calculation(like formula type etc...) Flags is mask of following constants:
DATALOST
this is set in case, that data in image was lost(image was cleared or resized or freshly allocated). Filters that uses data from previous frames should take care to this flag. Zooming engine for example recalculates whole image since pixels from previous frame was lost. Note that data should be lost also in case, filter receives different image that in previous initialization since some filter behind was removed.
An inhering process is done using function:

Function: void inhermisc (struct filter *f,struct initdata *i);

This function sets fields in filter structure like as fractalc or wait_func. Inhering of image is quite complex, since new image needs to be prepared for child. In order to save memory it is highly recomended to use same image or at least same memory for data when passing to child. But this is not allways possible. Following function implements heruistic to do this:

Function: int inherimage (struct filter *f,struct initdata *data, int flags, int width, int height, struct palette *palette, float pixelwidth, float pixelheight)
You should call this function in yout initialize pass. It fills image and childimage in filter structure, prepares initdata for child and creates image for child. Note that it should fail in some cases and return 0. In this case filter is expected to interrupt initialization and return 0 too.

An flags parameter is mask of following constants:

IMAGEDATA
in case your filter requires data from previous frame
TOUCHDATA
In case your filter touches data in output image. This is very usual but there is some filtrs (like interlace or subwindow that don't)
NEWIMAGE
Set in case your filter can not deal with shared images (images that have input data in same memory are as output)
Width and height should be set to 0 in case you want same width/height as in parent image or width and height of image you want to pass to child. Palette is palette of image you want to pass. Set to NULL if palette should be inhered from parent's image (usual). Pixelwidth and pixelheight specifies physical size of pixel in centimeters. If set to 0 they are inhered from parent's image.

In case you use inherimage mechanizm you also must call destroyinheredimage in destroyinstance function and updateinheredimage at the begining of calculate function.

Example implementation:
 
static int initialize(struct filter *f,struct initdata *i)
{struct stereogramdata *s=f->data;
  inhermisc(f,i);
  if(!inherimage(f,i,TOUCHIMAGE,0,0,NULL,0,0) return 0;
  /*initialize here*/
  return(f->previous->action->initialize(f->previous,i));
}
Also note that fractal context hold pointer to fractal palette. In case You don't change image palette everything is OK. But in case child's image differs from parents image, there should be two behaviours -- fractal's palette is child one (this should be common for example in conversion filters ( 8bpp to truecolor etc)) or fractal's palette is parent's one (like in edge detection filter). By default fractal's palette is kept to parent's one. This should be changed by setfractalpalette call. It has two parameters --- filter structure and palette. When you pass as palette child's palette, fractal's palette will be changed to child. In case you pass NULL. Changing of palette will be disabled (like in motion blur filter in 8bpp mode). Note that this is changed just in case you still have access to fractal palette. Some parent should redirect palette before. Than this functio does nothing.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster     delorie software   privacy  
  Copyright 2003   by The Free Software Foundation     Updated Jun 2003