Skip to topic | Skip to bottom
Home
Linfo
Linfo.CPetitProjetNovembre2004r1.7 - 06 Nov 2004 - 20:24 - OlivierDalletopic end

Start of topic | Skip to actions

C "petit-Projet" (novembre 2004)

Licence Informatique 2004-2005

Le travail demandé sera à réaliser en binome.

ALERT! Tous les étudiants sont priés de regarder les consignes pour la ConstitutionDesBinomes ...

Partie 1 : création d'un fichier bitmap X11

Le but de cette partie du projet est de faire un programme C qui fabrique un dessin au format bitmap X11. Le bitmap est la forme la plus simple d'image qu'on trouve sous Unix : l'image est un tableau de point qui peuvent être soit allumés (noirs) soit éteints (blancs). Pour coder l'état d'un point de l'image, il suffit d'un unique bit.

Exemple : le tableau suivant représente le bitmap d'un dessin de 5x5 qui contient un carré de 3x3 en haut à gauche :
11100
10100
11100
00000
00000

Dans ce projet, on vous demande de faire un programme C qui soit capable de fabriquer un bitmap correspondant au dessin de vos initiales (donc 4 lettres par binôme).
Les initiales devront être dessinées en majuscule, en utilisant une écriture "baton" simple.
Les caractères devront avoir une taille fixe de 6 points de large, et 8 points de haut.
L'espace entre chaque caractère ou entre les caractères et le bord du dessin devra être de 2 points. Avec un point supplémentaire au milieu entre les 2 paires d'initiales.
Par exemple, le dessin des initiales de Olivier Dalle et Octave Dupont est le suivant (4 caractères + espaces = 37x13) :
0000000000000000000000000000000000000
0000000000000000000000000000000000000
0001111000111110000000111100011111000
0010000100100001000001000010010000100
0010000100100001000001000010010000100
0010000100100001000001000010010000100
0010000100100001000001000010010000100
0010000100100001000001000010010000100
0010000100100001000001000010010000100
0001111000111110000000111100011111000
0000000000000000000000000000000000000
0000000000000000000000000000000000000

Etape 1 : construction de l'image en mémoire

La première étape du programme consiste donc à fabriquer l'image en mémoire du bitmap, sachant bien sûr que les bits de l'image sont stockés sous forme d'octets, donc 8 par 8, dans un tableau d'octets (type unsigned char ) en mémoire. Chaque ligne de points du dessin ne correspond pas forcément à un multiple de 8 points. Comme certains d'entre-vous l'ont remarqué en regardant de près le résultat produit par la commande bitmap , cette irrégularité est corrigée à chaque fin ligne en ajoutant quelques bits (points virtuels) pour tomber exactement sur un multiple de 8 bits :

11100000
10100000
11100000
00000000
00000000

Par ailleurs, lorsque l'on regarde l'image de gauche à droite, les bits correspondant à chaque point sont numérotés dans l'ordre croissant. Ce qui revient à stocker ces bits dans l'odre inverse de la convention usuelle de lecture (et d'affichage) des nombres :

Ainsi, le contenu du tableau d'octets correspondant au petit dessin de 5x5 en haut de cette page est le suivant (lorsque les bits sont affichés dans le bon sens) :
tab[0] = 00000111 = 0x07
tab[1] = 00000101 = 0x05
tab[2] = 00000111 = 0x07
tab[3] = 00000000 = 0x00
tab[4] = 00000000 = 0x00

Un conseil pour commencer : écrivez une fonction set_bit(x,y) qui "allume" (fait passer à 1) le point de coordonnées (x,y).

Il n'est bien sûr pas question que vous fassiez un programme qui dessine vos initiales point par point ! Pour faciliter la lisibilité de votre programme, vous créerez des fonctions de tracé, comme par exemple une fonction ligne(x0,y0,x1,y1) , qui tracerait une ligne entre les points de coordonnées (x0,y0) et (x1,y1). Ainsi le dessin de la lettre 0 doit pouvoir s'écrire simplement à l'aide d'appels tels que les suivants:
ligne(4,3,7,3); /* sommet du O */
ligne(8,4,8,9); /* coté droit du O */
...

Vous devrez par ailleurs associer des commentaires explicites à chaque appel de fonction de tracé pour que votre programme soit parfaitement compréhensible (comme dans l'exemple précédent).

Etape 2 : Sauvegarde de l'image

La deuxième étape consiste à écrire une fonction qui permet de sauvegarder votre image dans un fichier. Le format de sauvegarde est est assez simple puisqu'il s'agit d'un format texte.

Voici par exemple le fichier obtenu lors de la sauvegarde de notre petit exemple 5x5 du début, à l'aide de la comande unix bitmap (essayez-la !) :


#define exemple5x5_width 5
#define exemple5x5_height 5
static unsigned char exemple5x5_bits[] = {
   0x07, 0x05, 0x07, 0x00, 0x00};

Vous remarquerez qu'il s'agit d'instructions du langage C ! Mais peu importe. Ce qui nous intéresse c'est d'être capable de produire un résultat similaire en adoptant des règles de sauvegarde strictement identiques :

  • Les deux premières lignes indiquent la taille du bitmap
  • Vient ensuite la définition du tableau d'octets, qui doit respecter strictement les règles de mise en page suivantes :
    • Valeurs des octets exprimées en hexadécimal
    • 3 espaces en début de ligne
    • 1 espace entre 2 valeurs consécutives sur une ligne
    • 12 valeurs maximum par ligne

Voici un autre exemple avec une image un peu plus grosse (12x14) pour illustrer les règles de mise en page précédentes (pour les curieux, l'image correspondante est présentée juste après, au début de la 2e partie du sujet) :


#define image12x14_width 12
#define image12x14_height 14
static unsigned char image12x14_bits[] = {
   0x07, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0e,
   0x00, 0x00, 0x00, 0x00};

Pour réaliser la sauvegarde, vous ajouterez donc une fonction spécialisée pour cette tâche au programme de l'étape précédente, et qui sera appelée à la fin de votre programme, lorsque le dessin sera terminé.

Partie 2 : conversion ascii <-> bitmap X11

Réécrivez une version simplifiée de chacune des deux fonctions de conversion atobm et bmtoa qui permettent de convertir un fichier au format précédent en une version plus lisible et inversement. Version simplifiée signifiant que vous ne vous préoccuperez pas des nombreuses options décrites dans la page de manuel de ces deux commandes. Voici un exemple du résulat produit par la commande bmtoa sur le fichier "image12x14" présenté plus haut :

dalle@fortissimo_~$ bmtoa image12x14                                        [~]
###---------
#-#---------
###---------
------------
------------
------------
------------
------------
------------
---------###
---------#-#
---------###
------------
------------

Vos programmes devront lire les images du format initial à partir d'un fichier dont le nom sera donné en paramètre du programme, ou à defaut, sur leur entrée standard, et afficher le résultat de la conversion sur la sortie standard.

Notez bien que dans le sens atobm (ascii to bitmap), l'affichage ne pourra pas commencer avant que les données aient été entièrement lues (pour connaître le nombre de lignes).

Recommandations

  • Vous l'aurez compris, le but de l'exercice est de vous entraîner à utiliser les opérateurs binaires et de travailler sur les bits qui constituent l'image. Il est donc formellement interdit de construire et travailler sur une image en mémoire autrement que sous forme binaire. Il est en particulier interdit de fabriquer l'image à l'aide de chaînes contenant les caractères "0" et "1" !
  • A titre indicatif, chaque programme doit représenter environ entre 50 et 100 lignes de C (en ne comptant pas les lignes vides et les commentaires). Si vous vous rendez compte que vos programmes commencent à dépasser 100 lignes, posez-vous des questions, il y a certainement pas mal de choses qui méritent d'être simplifiées ... Nous ne corrigerons pas les programmes qui sont excessivement (et inutilement) longs ! (cad > 150 lignes de C hors commentaires et lignes vides).
  • La contrainte précédente ne doit surtout pas vous pousser à faire des lignes de programme gigantesques ! Un "beau" programme comporte des lignes de C d'au maximum 80 caractères : des lignes trop longues sont rapidement illisibles...
  • Dans le même ordre d'idée, évitez les "cascades" de plus de 3 niveaux. Cad évitez d'emboiter un trop grand nombre de choses (boucles for, if, etc). On peut toujours s'en sortir autrement, en particulier en définissant des fonctions intermédiaires. Vous verrez que vous même vous comprenez mieux ce que vous écrivez en respectant cette règle !
  • Indentez proprement vos programmes. Et commentez-les de façon utile.
  • Testez rigoureusement le bon fonctionnement de vos programmes, notamment à l'aide des commandes unix bitmap, bmtoa et atobm .
  • Assurez-vous que votre programme compile sans aucune erreur en utilisant les options suivantes du compilateur :
     gcc -Wall -ansi -pedantic -Werror 

Enfin une petite mise en garde pour ceux d'entre-vous qui seraient tentés de copier tout ou partie de leur projet sur leurs camarades (ou d'en récupérer des parties sur internet ou ailleurs) : vos enseignants ne sont pas nés de la dernière pluie ! Dites-vous bien que toute tentative de copie sera détectée et bien-sûr sévèrement sanctionnée, tant du coté des copieurs que celui des étudiants qui auront laissé d'autres étudiants copier leur travail. Pour éviter toute surprise désagréable, pensez-donc à protéger votre de répertoire de travail avec les permissions unix adéquates pour empêcher la copie ...

Date de remise des projets

Semaine du 15 novembre 2004. Les modalités de remise vous seront précisées très bientôt.


-- OlivierDalle - 02 Nov 2004


Permissions
to top

You are here: Linfo > WebTopicList > CPetitProjetNovembre2004

to top

Copyright © 1999-2020 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding WIKIDeptinfo? Send feedback