Le projet proposé ici consiste à développer en ADA des paquetages génériques sur les arbres
n-aires et quaternaires. Ces paquetages seront réutilisés pour implanter un autre
paquetage permettant de faire de la compression et décompression d'images.
Les opérations que l'on doit faire sur un arbre n-aire se classent en 3 catégories:
création, consultation et modification. Voici la liste des procédures à implanter.
An_Changer_Valeur: qui change la valeur rangée à la racine d'un arbre.
An_Inserer_Fils: qui insère un arbre sans frère en position de premier
fils d'un arbre a. L'ancien fils de a devient le premier frère de l'arbre inséré.
An_Inserer_Frere: qui insère un arbre sans frère en position de premier
frère d'un arbre a.
An_Supprimer_Fils: qui supprime le nième fils d'un arbre a.
An_Supprimer_Frere: qui supprime le nième frère d'un arbre a.
An_Changer: qui applique une fonction à chaque élément de l'arbre.
Un noeud est représenté par un enregistrement contenant la valeur de la racine,
un pointeur sur le premier fils, un pointeur sur le frère et un pointeur sur le père
de l'arbre. Le type arb_nr est mis en private pour cacher à l'utilisateur du
paquetage la structure de données choisie pour représenter l'arbre n-aire.
Nous avons choisi de
passer en paramètres génériques le type de la valeur de la racine, la procédure
qui permet d'afficher un élément et la fonction qui sera appliquée à chaque élément :
Pour l'affichage de l'arbre, nous utilisons une procédure auxiliaire récursive
qui permettra de parcourir l'arbre.
La procédure auxiliaire est la suivante.
Nous parcourons tout d'abord dans le sens des premiers fils avec un décalage dans
l'affichage puis dans le sens
des frères en gardant le même décalage pour tous les frères.
Nous utilisons ici aussi une procédure auxiliaire qui permettra de parcourir l'arbre
dans les deux sens de récursivité, fils et frères.
La procédure auxiliaire est la suivante. Nous nous servons d'un booléen passé en
données/résultats pour terminer les appels récursifs dans le cas où la valeur est
trouvée. Si elle n'est pas trouvée, arb_cour sera un pointeur null.
Les arbres quaternaires étant une sous-catégorie des arbres n-aires, nous
définissons un type arbre quaternaire sous-type des arbres n-aires. Les
paramètres génériques sont les mêmes que ceux du paquetage arbre n-aire.
Nous utilisons la directive ADA "renames" dans la partie spécification qui
nous permet de réutiliser les procédures et fonctions implantés dans le paquetage arbre n-aire.
exemple:
Nous faisons de même pour les exceptions:
Nous définissons une exception filsq_vide pour la procédure Aq_Construire.
Le but est de compresser et décompresser une image en utilisant un
arbre quaternaire. Les images que nous utilisons sont carrées et leur
dimension est une puissance de 2. Une couleur est définie à partir des
3 couleurs de base rouge, vert, bleu et est codée sur un entier.
Le principe d'encodage récursif d'une image de dimension n est le
suivant: si l'image est homogène, on crée une feuille
dont la valeur est la couleur de l'image. Si l'image n'est pas homogène,
on la découpe en 4 sous-images de dimension n/2, et on crée un arbre
quaternaire dont les quatre fils sont les encodages des quatre sous-images.
En parcourant en profondeur l'arbre quaternaire, nous obtenons une suite
de valeurs représentant l'image compressée.
Il est demandé de réaliser un paquetage permettant de:
créer ue image à partir d'une dimension et d'une matrice.
Nous choisissons de représenter une couleur par une valeur codée sur 32 bits
(pixel). L'image est une matrice de pixels. Nous utilisons des
tableaux non contraints.
Nous détaillons ici la fonction est_homogene en distinguant 3 cas : la
tolérance est minimale (0), maximale(100) ou entre les deux. Si elle est
maximale, alors nous retournons le booléen égal à true et une feuille est crée
avec la couleur moyenne de la zone concernée (cf procédure im_to_arb). Si elle est minimale, on s'assure que tous
les pixels ont la même valeur. Enfin, pour le cas intermédiaire, nous regardons
si l'inégalité abs(couleur_primaire-moyenne) <= tolerance est vérifiée pour
chaque pixel et couleur primaire.
Il s'agit tout d'abord de construire l'arbre à partir de la séquence
encodée (procédure charger_im_encod et imc_to_arb) puis de reconstruire l'image à
partir de cet arbre (procédure arb_to_im).
Nous devons reconstituer l'image à partir de l'arbre. l'arbre est arb_im et
l'image résultante est im. Nous nous servons des indices i_d,i_f,j_d,j_f
pour obtenir le décalage entre les appels récursifs.
Les programmes de test main_arb_nr.adb et main_arb_quater.adb utilisent
respectivement les paquetages arb_nr.db et arb_quater.adb. Il est possible
de construire un arbre pour vérifier le bon fonctionnement des différentes
procédures et fonctions.
Le programme de test main_pimage.adb permet de créer une image
pour valider la compression et décompression. L'affichage des couleurs de
cette image est représentée sur la figure suivante:
Figure 1 : Contenu de l'image test 8x8
Sa taille est égale à 260 octets (64*4+4) car nous stockons aussi la
dimension. On vérifie maintenant la compression. Nous prenons en compte une tolérance pour
déterminer si une image est homogène. L'arbre construit avec une tolérance minimale (0)
est représenté sur la figure suivante:
Figure 2 : Affichage de l'arbre obtenu pour la compression avec une tolérance minimale
La taille de l'image compressée est égale à 104 octets (25*4+4) dont 4 octets pour
la dimension, ce qui est bien le résultat attendu.
Pour une tolérance maximale (100), nous obtenons une feuille avec la couleur moyenne de
l'image (161) car celle-ci est considérée comme homogène d'après le critère dans la
fonction est_homogene.
Avec une tolérance égale à 80, nous obtenon l'arbre suivant :
Figure 3 : Affichage de l'arbre obtenu pour la compression avec une tolérance de 80
Nous remarquons qu'il y aura une perte d'information par rapport à l'image test dans la décompression
car la partie Nord Ouest de l'image est considérée comme homogène avec cette tolérance. Ceci
est illustré sur la figure suivante :
Figure 4 : Contenu de l'image test 8x8 décompréssée avec une tolérance initiale de 80
Nous enregistrons pour chaque cas l'image compréssée puis vérifions la décompression.
Ce projet nous a permis de créer un paquetage permettant de faire de la
compression et décompression d'images. Les opérations implantées pour les
arbres quaternaires ont été réutilisées et validées dans l'algorithme
d'encodage.