Langage C – Jouons avec les fichiers BMP, la suite

Logo X11

Sur la lancée de mon article précédent, j’ai continué à écrire ma bibliothèque en langage C qui permet de gérer les fichiers BMP. Pour être sûr de son bon fonctionnement, j’ai décidé de la lier avec un framework graphique qui me permettrait d’afficher les fichiers BMP ouverts avec ma librairie. J’ai opté pour le X Window System (X11), l’IHM standard de la majorité des systèmes Unix. Pour utiliser X11 il faut passer par la bibliothèque Xlib qui propose une interface bas niveau, permettant de communiquer avec le serveur X. J’ai vite compris qu’il me fallait instancier une Window et y déposer une XImage laquelle contenant les données du fichier BMP. Le problème c’est de faire en sorte que le données lues depuis le BMP soient compatibles avec celles nécessaires à la structure XImage. Pour cela il m’a fallu écrire de nouvelles fonctions pour:

  • Inverser les lignes de données (le fichier bmp enregistre les données de la dernière ligne à la première).
  • Supprimer les bits de padding à chaque fin de ligne.
  • Convertir les pixels sur 24 bits en pixel sur 32 bits.
  • Invertir les valeurs RGB en BGR (non nécéssaire pour X11, mais pour le Graphic Target Framework utilisé au boulot).

Les sources sont toujours disponibles ici.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Read all the line of the pData.
// First line becomes the last one and so one...
// Return a pointer on the memory area containing the new data.
uint8_t *
BmpWorker_RawData_invertLines(const uint8_t *pData, const uint32_t nLines,
                              const uint32_t bytes_per_line);
 
// Add a fourth byte (0xFF) to each pixel. This is useful for making
// the bmp data content compatible with other image datatype
// e.g: XImage
// Return a pointer to the memory area containing the data
// with 4 bytes depth pixels.
uint8_t *
BmpWorker_RawData_make4BytesCompatible(const uint8_t * pData,
                                       const uint32_t pData_size);
 
// Some images have the pixel colors coded in another direction.
// This function invert the colors. From RGB to BGR.
// pData MUST have a 24bits (3 bytes) depth.
uint8_t *
BmpWorker_RawData_invertRBValues(const uint8_t * pData, const uint32_t pData_size);
 
// The bits representing the bitmap pixels are packed in rows.
// The size of each row is rounded up to a multiple of 4 bytes by padding.
uint8_t *
BmpWorker_RawData_removeEndlinePaddingBytes(const uint8_t * pData,
                                    const BmpWorker_infoHeader * infoHeader);

Ces étapes réalisées, il est possible d’afficher le contenu d’une BMP dans une fenêtre X, la preuve en image:

X11 étant une IHM vieillissante et complexe, la majorité des utilisateurs se tournent vers des surcouches tel que GTK+ ou QT. Il y a, par conséquent, peu de tutoriels relatifs à Xlib sur internet, je n’ai trouvé que le site de Pierre Ficheux avec ses deux anciens articles: Introduction à la programmation Xlib et Couleurs, Images et Xlib. De plus, il existe le Xlib manual de Christophe Tronche. Enfin la documentation officielle: C Language X Interface.

A savoir que pour X11 sera remplacé par Wayland dans les prochaines versions d’Ubuntu.

2 thoughts on “Langage C – Jouons avec les fichiers BMP, la suite

  1. Bonjour, bonne idée et bien complète ta librairie.
    Par contre, elle leak à chaque fois que tu retourne un tableau.
    tu devrais préférer modifier le tableau passer en argument et utiliser un memcpy…

    J’ai modifier ta lib en conséquence, je peux te fournir la version modifiée si elle t’intéreresse.

    • Merci pour ton commentaire, oui je serais intéressé par les modifications. Je peux soit essayer de te donner un accès en écriture au SVN ou alors tu peux m’envoyer un zip à thomas[_at_]bores[_dot_]fr. Comme tu préfères.

Leave a Reply

%d bloggers like this: