1. Plan
- creating function in a star
- memory management in a star
- using messages
2. Creating functions in a star
Consider the following C code :
///////////////// START OF A NEW LISTING PART ////////////////
void swap_int (int *s) {
/* Swap a 32 bits integer like this:
| 0 | 1 | 2 | 3 | => | 3 | 2 | 1 | 0 |
*/
unsigned char *b ;
unsigned char t ;
//
b = (unsigned char *)s ;
t = b[0] ;
b[0] = b[3] ;
b[3] = t ;
//
t = b[1] ;
b[1] = b[2] ;
b[2] = t ;
}
It may be integrated within a star source code with the following syntax :
///////////////// START OF A NEW LISTING PART ////////////////method {
name { swap_int }
type { "void" }
arglist { "(int *s)" }
access { protected}
code {
/* Swap a 32 bits integer like this
| 0 | 1 | 2 | 3 | => | 3 | 2 | 1 | 0 |
*/
unsigned char *b ;
unsigned char t ;
//
b = (unsigned char *)s ;
t = b[0] ;
b[0] = b[3] ;
b[3] = t ;
//
t = b[1] ;
b[1] = b[2] ;
b[2] = t ;
} // end of code
} // end of method
3. Memory management
- Ptolemy is a big software =>
- However, different ways to handle memory management :
- never free something that you send on output,
- concerning the rest, no leaks are allowed
- never free something that you send on output,
- Problems come from memory staying from one go to the other : very, very careful management is required,
- declare within protected
- initialise within constructor
- FREE and allocate within setup
- use within go
- free and INITIALISE in wrapup
- free in destructor (not mandatory)
- declare within protected
SETUP MAY BE CALLED MORE THAN ONCE
4. Memory management - malloc example
///////////////// START OF A NEW LISTING PART ////////////////
protected {
int *test;
}
constructor {
test = NULL;
}
setup {
free(test);
test =
(int *)malloc(sizeof(int)*int(A_PARAMETER));
}
go {
int *fill_test;
fill_test=test;
for(i = 0; i< A_PARAMETER; i++) {
*fill_test = ......
fill_test++;
}
....
}
wrapup {
free(test);
test=NULL;
}
destructor {
free(test);
}
5. Memory management - new and delete
///////////////// START OF A NEW LISTING PART ////////////////
protected {
GrayImage *ref_pix;
}
constructor {
ref_pix = 0;
}
setup {
if (int(DEBUG)>0) {
printf("Setup Memory Management");
fflush(stdout);
}
delete ref_pix;
ref_pix = new GrayImage(int(WIDTH_PARAM),int(HEIGHT_PARAM),0);
}
go {
if (int(DEBUG)>0) {
printf("Go Memory Management");
fflush(stdout);
}
Envelope img_envlp;
(input_pixel_frame%0).getMessage(img_envlp);
TYPE_CHECK(img_envlp,"GrayImage");
GrayImage *input_pix=(GrayImage *)img_envlp.myData();
Envelope img_envlp;
(input_pixel_frame%0).getMessage(img_envlp);
TYPE_CHECK(img_envlp,"GrayImage");
GrayImage *input_pix=(GrayImage *)img_envlp.myData();
(char *)current_input_pix = input_pix->retData();
(char *)current_ref_pix = ref_pix->retData();
if ( input_pix->GetWidth() == ref_pix->GetWidth() ) {
for ( int i = 0; i < int(WIDTH_PARAM); i++) {
for ( int j=0; j<int(HEIGHT_PARAM); j++) {
*current_ref_pix = *current_input_pix;
current_ref_pix++;
current_input_pix++;
}
}
}
GrayImage *output_pix = new GrayImage(*ref_pix);
Envelope out_pix_envlp(*output_pix);
current_pixel_frame%0<<out_pix_envlp;
} // end go
wrapup {
if (int(DEBUG)>0) {
printf("ReorderFrame Begin Wrapup");
fflush( stdout);
}
delete ref_pix;
ref_pix =0;
} // end wrapup
destructor {
delete ref_pix;
}
6. The message class
- the 'message' class is an object class that has been design to facilitate the communication between stars
- a 'message' is considered by the scheduler as another particle which go from one block to another in one firing
- a 'message' is transmitted within an 'enveloppe' which contains:
- a description of the data: data type, data number, ...
- the data themselves
- a description of the data: data type, data number, ...
- within '.pl' files, objects are managed through their 'Envelope'

7. The matrix class
Ptolemy has its own matrix class. You may create ComplexMatrix, FloatMatrix, FixMatrix and IntMatrix.Most of the time, you will not allocate static matrices, but you will create pointers to matrices.
FloatMatrix *ImageMatrix = new FloatMatrix(12,10);
A pointer to a matrices of 12 rows and 10 columns was created.
To get the size of a matrix use functions :
numRows()
numCols()
So for example :
width = ImageMatrix->numCols();
height = ImageMatrix->numRows();
There are many ways to access the elements of a matrix. The simplest one is :
FloatMatrix A(10,12);
s=A[1][5]
So if we deal with matrix pointers :
FloatMatrix *A = new FloatMatrix(12,10);
s=(*A)[1][5]
or
(*A)[2][6] = (*A)[3][7]
The entry function allows to get an element of the matrix directly. Its use allow to quickly walk through all values of a matrix.
s=A->entry(5+1*A->numCols());
Finally the pure C method would be to use pointers :
double* d = &(imgData->entry(0));
double s;
for ... {
s += *d++;}
8. Matrix use example
Copy of an input matrix on an output matrix
///////////////// START OF A NEW LISTING PART ////////////////
defstar {
name { CopyImage }
domain { SDF }
version { %W% %G% }
author { AL }
copyright{
}
location { SDF User library }
desc {
Copie une image de l'entree sur la sortie
}
// permet de faire un ou plusieurs include de fichiers
hinclude { "Matrix.h" "iostream.h" }
input {
name { InputPic }
type { FLOAT_MATRIX_ENV }
desc { Input grey level picture }
}
output {
name { OutputPic }
type { FLOAT_MATRIX_ENV }
desc { Output grey level picture }
}
go {
Envelope envp;
(InputPic%0).getMessage (envp);
// Creation de la matrice qui va contenir les donnees d'entrees
const FloatMatrix *InputMatrix = (const FloatMatrix*) envp.myData();
// Void input picture ?
if (envp.empty()) {
// L'enveloppe vide est envoyee a la sortie output
OutputPic%0 << envp;
} // end if empty
else { // not empty normal processing
// Recuperation de la largeur de l'image d'entree
int width = InputMatrix->numCols();
// Recuperation de la hauteur
int height = InputMatrix->numRows();
// Initialisation de la matrice de sortie
FloatMatrix *OutputMatrix =new FloatMatrix(height,width);
// Boucle de copie
int i,j;
for ( i=0; i<height; i++ ) {
for ( j=0; j<width; j++ ) {
// Copie d'un pixel d'entree dans le pixel correspondant
// de sortie
(*OutputMatrix)[i][j] = (*InputMatrix)[i][j];
}
}
// L'enveloppe est envoyee a la sortie output
// L'image resultat est mise dans une enveloppe
Envelope envp2(*OutputMatrix);
OutputPic%0 << envp2;
}
} // end go
} // end CopyImage
//////////////////////////////////////////
This is a pedagogical example, it is possible to directly use the copy constructor :
FloatMatrix *OutputMatrix =new FloatMatrix(*InputMatrix);
All informations concerning the Matrix class may be found in the Ptolemy Programmer's Manual at chapter 4 - Data Types.
10. Matrix use example test schematic

11. Matrix use example
///////////////// START OF A NEW LISTING PART ////////////////
hinclude { "Matrix.h" }
input {
name { InputPic }
type { FLOAT_MATRIX_ENV }
desc { Input grey level picture }
}
go {
Envelope envp;
(InputPic%0).getMessage (envp);
const FloatMatrix *Input = (const FloatMatrix*) envp.myData();
// Void input picture ?
if (envp.empty()) {
FloatMatrix *CopyInput = new FloatMatrix();
Output%0<< *CopyInput;
} // end for
} // end if empty
else { // not empty normal processing
FloatMatrix *Output =new FloatMatrix(Input);
...........
OutputFrame<<*Output;
}
10. Message class example
///////////////// START OF A NEW LISTING PART ////////////////
hinclude { "BaseImage.h","GrayImage.h","Matrix.h", <std.h>, <stdio.h> }
ccinclude { "BaseImage.cc","GrayImage.cc" }
output { name { output } type { message }
go {
.............
GrayImage* imgData = new GrayImage(hd1.pels,hd1.lins, current_frame_number);
.............
// Write the new frame to output...
Envelope envp(*imgData); output%0 << envp;
}
![]() |
Précédent | Suivant | Plan | 13/03/00 | PTOLAB |

