Vendredi soir, pas assez motivé pour sortir, je me suis lancé dans une séance programmation. J’ai pris pour thème le traitement d’image bas niveau, effectivement jusqu’à présent j’avais toujours utilisé des librairies pour traiter les images. Pour ne pas faire trop compliqué, je me suis concentré sur un format d’image non compressé et assez courant: le bitmap. Je me suis alors plongé dans la lecture du très bon article anglais de wikipedia qui décrit ce format. Pendant ces quelques heures j’ai appris notamment que les pixels sont codés en commençant par le premier à gauche de la ligne inférieur de l’image, étonnant quand on est habitué à partir de la ligne supérieur (c’est la cas de la plupart des autres formats). Pour vérifier mes résultats j’ai du utiliser un éditeur hexadécimal, j’ai alors découvert GHex sur Ubuntu, je dois dire que je lui préfère celui de Notepad++.
Ci dessous la liste des fonctions que j’ai implémenté. La base, pour lire et écrire un fichier bitmap, est présente. Après je n’ai eu le temps d’implémenter qu’une seule fonction de modification, qui permet de changer tous les pixels blancs en pixels noirs
Le code est disponible dans son intégralité et sous licence BSD sur SourceForge.
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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
// Return the size of the file header (14 bytes) uint32_t BmpWorker_FileHeader_size(); // Display on the console the content of the File Header void BmpWorker_FileHeader_display(const BmpWorker_fileHeader * fileHeader); // Read the File Header from the bitmap file and save it in the header parameter. int8_t BmpWorker_FileHeader_read(FILE * fBMP, BmpWorker_fileHeader * fileHeader); // Write the File Head in the bitmap file. int8_t BmpWorker_FileHeader_write(FILE * fBMP, const BmpWorker_fileHeader * fileHeader); // Display on the console the content of the File Header void BmpWorker_InfoHeader_display(const BmpWorker_infoHeader * infoHeader); // Read the Information Header from the bitmap file and save it in the // header parameter int8_t BmpWorker_InfoHeader_read(FILE * fBMP, BmpWorker_infoHeader * infoHeader); // Write the information in the bitmap file. int8_t BmpWorker_InfoHeader_write(FILE * fBMP, const BmpWorker_infoHeader * infoHeader); // Read the bitmap data and save it in the pData pointer int8_t BmpWorker_RawData_read(FILE * fBMP, const BmpWorker_fileHeader * fileHeader, const BmpWorker_infoHeader * infoHeader, uint8_t * pData); // Display on the console all the pixels of the bitmap data. void BmpWorker_RawData_display(const BmpWorker_infoHeader * infoHeader, const uint8_t * pData); // Change all the white pixels in pData in black ones void BmpWorker_RawData_white2black(const BmpWorker_infoHeader * infoHeader, uint8_t * pData); // Save only the pData in the fBMP file void BmpWorker_RawData_write(FILE * fBMP, const BmpWorker_fileHeader * fileHeader, const BmpWorker_infoHeader * infoHeader, const uint8_t * pData); // Write the all data in a file named fileName int8_t BmpWorker_SaveOnDisk(char * fileName, const BmpWorker_fileHeader * fileHeader, const BmpWorker_infoHeader * infoHeader, const uint8_t * pData);