Voyons à présent ce que contient la fonction get_image_info (le code de celle-ci doit se trouver dans le fichier qmtcl1.cpp) :

// *************** get_image_info *******************
// Fonction interne récupérant des paramètres
// de l'image dont le numéro de buffer est
// contenu dans la variable n_buffer. Le résultat est
// retourné dans une structure IMAGE.
// On retourne :
//    - le pointeur mémoire vers l'image
//    - la taille de l'image (imax, jmax)
//    - les seuils de visualisation courants (sh, sb)
// **************************************************

int get_image_info(IMAGE **image,int n_buffer,Tcl_Interp *interp)
{
static IMAGE info;
int i,retour;
char s[256];

// Lit le pointeur image
// ---------------------

sprintf(s,"buf%d pointer",n_buffer);
retour=Tcl_Eval(interp,s);
if (retour!=TCL_OK) return retour;
retour=Tcl_GetInt(interp,interp->result,&i);
if (retour!=TCL_OK) return retour;
info.p=(short *)i;
if (info.p==NULL)
   {
   Tcl_SetResult(interp,"Image non valide",TCL_DYNAMIC);
   return TCL_ERROR;
   }

// Lit la dimension imax
// ---------------------

sprintf(s,"lindex [buf%d getkwd NAXIS1] 1",n_buffer);
retour=Tcl_Eval(interp,s);
if (retour!=TCL_OK) return retour;
retour=Tcl_GetInt(interp,interp->result,&i);
if (retour!=TCL_OK) return retour;
info.imax=(short)i;

// Lit la dimension jmax
// ---------------------

sprintf(s,"lindex [buf%d getkwd NAXIS2] 1",n_buffer);
retour=Tcl_Eval(interp,s);
if (retour!=TCL_OK) return retour;
retour=Tcl_GetInt(interp,interp->result,&i);
if (retour!=TCL_OK) return retour;
info.jmax=(short)i;

// Lit le seuil haut
// -----------------

sprintf(s,"lindex [buf%d getkwd MIPS-HI] 1",n_buffer);
retour=Tcl_Eval(interp,s);
if (retour!=TCL_OK) return retour;
retour=Tcl_GetInt(interp,interp->result,&i);
if (retour!=TCL_OK) return retour;
info.sh=(short)i;

// Lit le seuil bas
// ----------------

sprintf(s,"lindex [buf%d getkwd MIPS-LO] 1",n_buffer);
retour=Tcl_Eval(interp,s);
if (retour!=TCL_OK) return retour;
retour=Tcl_GetInt(interp,interp->result,&i);
if (retour!=TCL_OK) return retour;
info.sb=(short)i;

*image=&info;
return TCL_OK;
}

Ce code est très caractéristique de la programmation d'une librairie pour Tcl. Il montre les étroites liaisons se tissant entre vos propres fonctions C, la bibliothèque Tcl/Tk et les bibliothèques de bases du système Audela.

Dans Audela lorsque vous chargez une image (obligatoirement au format FITS) un certains nombre de variables systèmes sont affectés. Parfois le nom de ces variables est le même que le nom des rubriques dans un fichiers FITS (NAXIS1 par exemple). Il suffit donc de lire ces variables pour tout connaître de l'image qui réside actuellement en mémoire.

Par exemple, si après avoir chargé une image vous tapez dans la console de AUDACE la commande suivante (voir le manuel de référence de Audela) :

lindex [buf1 getkwd NAXIS1] 1

le programme retourne la largeur de l'image en pixel.

Cette commande peut être exécuté depuis votre propre code C en utilisant une fonction de la librairie Tcl qui s'appelle Tcl_Eval. Par exemple :

retour=Tcl_Eval(interp,"lindex [buf1 getkwd NAXIS1] 1");

Une autre fonction de la librairie Tcl,  Tcl_GetInt, permet de lire le paramètre en retour de la précédente commande Tcl, paramètre qui est ensuite converti en un entier.

Illustrons l'usage de ces fonctions de la librairie Tcl pour lire l'adresse mémoire de l'image. Si depuis la console de AUDELA vous tapez :

BUF1 POINTER

la valeur en retour est directement l'adresse recherchée. Depuis votre code C, pour connaître l'adresse mémoire du premier pixel de l'image il suffit d'exécuter la petite commande précédente en invoquant l'interpréteur Tcl au travers de Tcl_Eval. Cette fonction accepte comme argument une chaîne de caractères qui n'est autre que l'intitulé de votre commande Tcl. Le second paramètre de Tcl_Eval est une chaîne de caractère qui contient le texte qui s'afficherai à l'écran en retour de l'execution de votre script. Dans notre cas la valeur en retour n'est autre que l'adresse de l'image. La mise en oeuvre est dès lors simple :

sprintf(s,"buf%d pointer",n_buffer);
retour=Tcl_Eval(interp,s);
if (retour!=TCL_OK) return retour;
retour=Tcl_GetInt(interp,interp->result,&i);
if (retour!=TCL_OK) return retour;
info.p=(short *)i;

La chaîne s est remplie avec le texte "buf1 pointer". On appelle ensuite Tcl_Eval avec ce paramètre. La variable interp est une structure qui contient de nombreuses informations concernant l'interpréteur Tcl. La variable interp->result pointe vers une chaîne de caractères qui n'est autre que la valeur en retour de la dernière fonction Tcl exécutée. La fonction Tcl_GetInt permet de convertir la chaîne en une valeur entière (la fonction C atoi fonctionne de la même manière et pourrait être utilisée ici). La valeur en retour est transformée finalement en un pointeur vers la zone mémoire de l'image.

La fonction get_image_info est déclarée de la manière suivante dans libqm.h :

int get_image_info(IMAGE **image,int buffer,Tcl_Interp *interp);

Il reste à faire le lien symbolique entre le nom de externe de la commande (qm_offset) et la fonction C corresdondante (CmdOffset). Cela est fait en ajoutant la ligne suivante dans libqm.cpp :

Tcl_CreateCommand(interp,"qm_offset",CmdOffset,(ClientData)NULL,
(Tcl_CmdDeleteProc *)NULL);
   

Compilez la bibliothèque et lancez l'interface AUDACE. Depuis la ligne de commande chargez une image. Par exemple :

LOADIMA  M57

Puis entrez les commandes suivantes dans la console :

QM_OFFSET 200
VISU
QM_OFFSET 100
VISU
QM_OFFSET -100
VISU

Vous verifiez ainsi que les offsets s'ajoutent ou se retranchent correctement .
 

                  (2/4)