Skip to topic | Skip to bottom
Home
Linfo
Linfo.CPetitProjetNovembre2004r1.9 - 14 Nov 2004 - 19:06 - 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 = 35x12) :
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

NEW Les projets sont à rendre à Olivier Dalle (dalle@unice.fr) au plus tard le jeudi 18/11 minuit.

Attention, la remise du projet est notée : ne perdez pas des points bêtement, suivez scrupuleusement les consignes suivantes !

Consignes de remise

Le projet doit être enregistré dans une archive .tgz construite de la façon suivante :
  1. Placer tous les fichiers dans un répertoire dont le nom est construit de la façon suivante :
    Nom1_Groupe1-Nom2_Groupe2.tar.gz
    Exemple : mkdir Buffa_2A-Dalle_1B
  2. Fabriquer le fichier archive contenant le répertoire précédent :
    Exemple : tar zcvf Buffa_2A-Dalle_1B.tgz Buffa_2A-Dalle_1B
  3. Envoyer l'archive en attachement d'un mail adressé à Olivier Dalle (encodage Base 64 sous exmh) en n'oubliant pas de vous mettre en copie du message. Utilisez impérativement une machine de l'université pour l'envoi (vos enseignants ont des protections anti-spam qui risquent de jeter automatiquement vos messages envoyés depuis l'exterieur...) Le message devra avoir un sujet respectant le modèle suivant :
    [L3O] Remise projet Nom1_Groupe1-Nom2_Groupe2
  4. Inutile d'envoyer plusieurs fois votre projet : si vous ne recevez pas de message d'erreur du "MAILER-DAEMON", c'est que l'envoi s'est a priori bien déroulé.
  5. N'envoyez pas plusieurs versions successives de votre projet : vous n'avez droit qu'à un seul envoi par binôme, assurez-vous qu'il s'agit de la bonne version avant de faire l'envoi (les envois suivants ne seront pas pris en compte)...

Confirmation de la remise

La liste des étudiants dont le projet aura été reçu correctement sera publiée sur cette page web vendredi à 14h au plus tard. Surveillez-là, si vous n'apparaissez pas dans la liste, c'est qu'il y a eu un problème de mail. Dans ce cas, procédez de la façon suivante :

  1. Composez un nouveau message contenant les attachements suivants :
    • La copie du message initial que vous avez du recevoir (puisque vous vous êtes mis en copie).
    • Les éventuels messages d'erreur reçus à la suite du premier envoi
  2. Envoyez le message à Olivier Dalle
  3. Par mesure de sécurité : téléchargez votre projet sur la page ou vous avez enregistré votre binôme :
    • Suivez le lien 'Attach' en haut de la page
    • A partir de la page wiki de téléchargement :
      • Cliquez sur le bouton 'Browse' pour indiquer au navigateur le chemin vers votre archive de projet
      • Cochez la case 'Link'
      • Cliquez sur le bouton 'Upload'


-- OlivierDalle - 02 Nov 2004


Permissions
to top

You are here: Linfo > WebTopicList > CPetitProjetNovembre2004

to top

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