next up previous contents index
Next: Some optimizations Up: Getting started Previous: Getting started   Contents   Index


A simple module

Let us suppose that you want to write an algorithm which adds the content of two monochrome images, that is to say it adds pixel by pixel the gray level values.

The first question you should ask yourself is ``what should be the input and the output of this algorithm ?''. Obviously you need two images for the input and the output will be another image, which will support the result of the addition. If you refer to the Volume two: ``MegaWave2 System Library'', you will see that monochrome images may be implemented by two MegaWave2 objects: the memory type Cimage and the memory type Fimage. The first one uses small integers for the gray levels (unsigned char) while the second one uses floating point representation. Let us say that your algorithm will make additions using the floating point representation: this is the less restrictive choice since integers are reals (and reals are not integers !) and the addition of two integers may exceed the capacity of the unsigned char representation (255).

Other important questions are ``what name should I give to the module ?'', ``what group should it belong to?''. Due to the limitation of some standard link editors and archives, we recommend you choose short names (with no more than 11 characters). One uses to begin the name with a letter which recalls the memory type of the input: here it will be f since we use Fimage. The remainder should be chosen in order to recall the algorithm, here add1 for example (the letter 1 means that variants will be presented). You may also want to put the module in a group, let us say demo.

At this point, we have all the information to write the MegaWave2 header (please have a look at the listing page [*]):

To be in concordance with this header, you must edit the module in a file called fadd1.c into the directory $MY_MEGAWAVE2/src/examples. This module is actually given with the standard distribution and it is located in $MEGAWAVE2/src/examples. So you can avoid editing it by copying it on your home location $MY_MEGAWAVE2/src/examples.

After the MegaWave2 header comes the regular C body. You must first include the needed standard C files (here stdio.h) followed by the MegaWave2 include file (mw.h).

The declaration of the main function (fadd1) must list all the parameters (and no others) put in the usage part of the header: you recognize the three parameters A,B,C. The body of this function uses several functions of the system library (all functions of the system library begin with the prefix mw). Please see the Volume two: ``MegaWave2 System Library'' to get explanations about all these functions.

The instructions

 if((A->nrow != B->nrow) || (A->ncol != B->ncol))
    mwerror(FATAL, 1, "The input images have not the same size!\n");
check that the sizes of the two input images A and B are the same, that is, that they have the same number of rows and columns. If not, a fatal error is sent, which terminates the module.

The line

  if ((C = mw_change_fimage(C,A->nrow,A->ncol)) == NULL)
    mwerror(FATAL, 1, "Not enough memory !\n");
allocates memory for the output image C, if C does not have enough memory to record a size of (A->nrow,A->ncol). Indeed, when you write a module, you don't know in which context the module may be executed: It can be run in the command mode, in which case no memory is allocated for C (but the C structure by itself) or it can be run as a function in memory (e.g. call from another module, from an interpreter, ...) in which case C may have been previously allocated.

The loop

 for (x=0;x<A->ncol;x++) for (y=0;y<A->nrow;y++)
    {
      a = mw_getdot_fimage(A,x,y);
      b = mw_getdot_fimage(B,x,y);
      mw_plot_fimage(C,x,y,a+b);
    }
is the main part of the algorithm: for each pixel (x, y), we get in a the gray level of the image A and in b the gray level of the image B . The last instruction makes the addition a+b and put the result in the image C.

We show in the following the whole listing of the simple module called fadd1:

/*--------------------------- MegaWave2 module -----------------------------*/
/* mwcommand
 name = {fadd1};
 author = {"My name"};
 labo = {"My labo with the address"};
 version = {"1.0"};
 function = {"Adds the pixel's gray-levels of two fimages (for demo #1)"};
 usage = {
   fimage1->A 
      "Input fimage #1", 
   fimage2->B
      "Input fimage #2", 
   result<-C
      "Output image"
};
*/
/*--------------------------------------------------------------------------*/

#include <stdio.h>
#include  "mw.h"

void fadd1(A,B,C)

Fimage  A,B,C;

{ int x,y;
  float a,b;

  if((A->nrow != B->nrow) || (A->ncol != B->ncol))
    mwerror(FATAL, 1, "The input images have not the same size!\n");

  if ((C = mw_change_fimage(C,A->nrow,A->ncol)) == NULL)
    mwerror(FATAL, 1, "Not enough memory !\n");  

  for (x=0;x<A->ncol;x++) for (y=0;y<A->nrow;y++)
    {
      a = mw_getdot_fimage(A,x,y);
      b = mw_getdot_fimage(B,x,y);
      mw_plot_fimage(C,x,y,a+b);
    }
}

You are now ready to compile the module: type under your favorite shell the command:
cmw2 fadd1
This assumes that you have a standard C compiler called cc. If your prefer to use the GNU C compiler, type the command:
cmw2 -gnu fadd1
You should get something like the following prints:

cmw2 fadd1 
 
>>> Welcome on the MegaWave2 Compiler V1.18 <<<
 
  Phase 1 : MegaWave2 preprocessor
fadd1.c :
done.
  Phase 2 : production of sources and objects
          production of document squeleton (doc/demo/fadd1.doc)
          production of arguments analyser object
          production of module object
          add objects to MegaWave2 user library
          production of interface with MegaWave2 interpretor source
          production of interface with MegaWave2 library object
  Phase 3 : production of MegaWave command
          linking MegaWave2 command "fadd1" on hp
     (New command added... Type rehash)

A lot of errors may occur during this compilation if your installation is not ready. In that case, please check the installation (see section 2).

If you didn't get any errors, type rehash if you are using a C-shell and execute the module in the command mode by typing fadd1 first without parameters. You should get something like:

-------------------------------------------------------------------------------
\\     //  Adds the pixel's gray-levels of two fimages (for demo #1).
 \\   //   
  fadd1    Copyright (C)1998 Jacques Froment. 
 //   \\   MegaWave2 : J.Froment (C)1988-98 CEREMADE, Univ. Paris-Dauphine
//V 1.0\\  and (C)1998-2002 CMLA, ENS Cachan, 94235 Cachan cedex, France.
-------------------------------------------------------------------------------

error : missing 'fimage1'

usage : fadd1 fimage1 fimage2 result

        fimage1 :       Input fimage #1
        fimage2 :       Input fimage #2
        result :        Output image
This print recalls you the syntax of the command. Since you run the module in the command mode, the parameters associated to a MegaWave2 type (fimage1 fimage2 result) refer to file names. If you have some favorite image files available, use them for the two requested inputs fimage1 fimage2. If not (or if MegaWave2 cannot read those file formats), type the line:
fadd1 fimage cimage result
How MegaWave2 does access to the files fimage and cimage ? If a file is not found in the given path and name (here ./fimage and ./cimage), MegaWave2 tries to resolve the name by reading the directories $MY_MEGAWAVE2/data and $MEGAWAVE2/data and their subdirectories. For each MegaWave2 internal type, we put in those directories examples of external types. The name of the file corresponds to the name of the internal type: for example, the file
$MEGAWAVE2/data/PUBLIC/cimage contains a monochrome image where the gray levels were recorded using the unsigned char representation, that is the representation of the Cimage internal type. You can display this image on your screen by calling the following public module:
cview cimage

You may have noticed that we called fadd1 with a parameter (cimage) which does not match the requested internal type for the C variable B (a Fimage). It doesn't matter since the MegaWave2 library makes the right conversion. It is also possible to convert a Fimage into a Cimage although is this case information may be lost. Of course some conversions are not supported (e.g. you cannot call fadd1 with a signal as parameter). Please refer to Volume two: ``MegaWave2 System Library'' to learn more about that.

After the command fadd1 fimage cimage result has been run, you should get on disk the new file ./result which records the contents of the C variable C. You can display it on the screen by typing:
cview result
You may get a warning message like
MegaWave warning (cview) : 27757 Gray levels were out of [0,255].
This is because cview takes a Cimage as the input, so the gray levels of result out of 255 have been thresholded.

Because C is a Fimage, the file ./result has a compatible format with the floating point representation. By default, MegaWave2 uses the same format as the format of the input fimage but you can choice the format you want by using the option -ftype. Indeed, there are some options in addition to the options you can define in the usage. Such options are called system's options and one can distinguish them from user's options since they use more than one letter (see section 4.8 page [*] for more details). For example, fadd1 -ftype IMG fimage cimage result2 creates a file result2 which has the external format IMG. This file format uses the unsigned char representation, therefore you get this warning during the execution of fadd1:
MegaWave warning (fadd1) : 27757 Gray levels were out of [0,255].
But now if you call cview result2, no more warning appears since thresholding has been done by fadd1.

If you want to print the output image on a PostScript printer, you should use the external format PS instead of IMG: the file result2 will contain the image following PostScript format, so you can print it using the command lp result2 (on most Unix systems). If you don't want to print result2 alone, e.g. if you want to include this file as an image in a LATEX document, you should use the EPSF format instead of PS.


next up previous contents index
Next: Some optimizations Up: Getting started Previous: Getting started   Contents   Index
mw 2004-05-05