Created
December 30, 2013 12:58
-
-
Save yfe404/8181833 to your computer and use it in GitHub Desktop.
Convert non standard format RGB32 to standard format PPM raw
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* \file main.c | |
* \brief Programme de conversion d'image rgb32 (non standard) vers PPM binaire (standard). | |
* \author Yann Feunteun | |
* \version 0.1 | |
* \date 30 décembre 2013 | |
* | |
* Ce programme convertit une image rgb32 dont le format est le suivant : | |
* | |
* 4 octets (unsigned) encodant la largeur | |
* 4 octets (unsigned) encodant la hauteur | |
* hauteur*largeur quadruplets d'octets. Chaque quadruplet se décompose en 1 octet pour la composante rouge (R), 1 octet pour la composante verte (G), un octet pour la composante bleu (B) et enfin un octet pour la composante alpha (A) (transparence). | |
* | |
* en format PPM binaire standard et affiche l'image sur la sortie standard. | |
* | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <errno.h> | |
#include <stdint.h> | |
/** | |
* \struct Img | |
* \brief Objet de gestion d'une image | |
* | |
* Objet constitué d'une structure contenant les champs largeur, | |
* hauteur et pointeur sur zone des pixels RGB allouée dynamiquement (de taille largeur*hauteur*3 octets). | |
*/ | |
typedef struct img | |
{ | |
uint32_t largeur, hauteur; /*!< Largeur et hauteur de l'image en pixels */ | |
unsigned char* addr; /*!< pointeur sur zone des pixels RGB. */ | |
}Img; | |
/** | |
* \fn void error(char *msg) | |
* \brief Fonction d'affichage d'erreur système. | |
* | |
* \param msg Message à afficher avant l'interprétation textuelle de errno (typiquement le nom de la fonction système utilisée) | |
*/ | |
void error(char *msg) | |
{ | |
fprintf(stderr, "%s : %s\n", msg, strerror(errno)); | |
exit(errno); | |
} | |
/** | |
* \fn void readImg(Img *img, char *fileName) | |
* \brief Fonction d'initialisation d'une structure Img avec les valeurs d'une image au format RGB32 | |
* | |
* Cette fonction initialise la structure passée en argument avec | |
* le contenu du fichier au format RGB32 (les quadruplets RGBA sont transformés en triplets RGB à cette occasion). | |
* | |
* \param img Un pointeur sur la structure Img à remplir | |
* \param fileName Le chemin d'accès à l'image RGB32 | |
* | |
*/ | |
void readImg(Img *img, char *fileName) | |
{ | |
uint32_t dimensions[2]; /*!< Stocke les dimensions de l'image RGB32 */ | |
uint8_t RGBA[4]; /*!< Stocke un quadruplet RGBA de l'image RGB32 */ | |
uint32_t j = 0; /*!< Compteur (pour parcourir la mémoire) */ | |
/*!< Ouverture du fichier RGB32 */ | |
FILE * rgb32 = fopen(fileName, "rb"); | |
if(rgb32 == NULL) | |
error("fopen()"); | |
/*!< Lecture des dimensions de l'image */ | |
if (fread(dimensions, 4, 2, rgb32) < 2) | |
error("fread()"); | |
/*!< Remplissage de la structure Img avec les dimensions lues */ | |
img->largeur = dimensions[0]; | |
img->hauteur = dimensions[1]; | |
/*!< Allocation dynamique de img->addr */ | |
img->addr = (uint8_t*)malloc((img->hauteur)*(img->largeur)*3); | |
if(img->addr == NULL) | |
error("malloc()"); | |
/*!< Lecture des quadruplets de l'image RGB32 et copie des trois premiers octets dans la zone img->addr */ | |
while(fread(RGBA, 1, 4, rgb32) == 4){ | |
memcpy(img->addr+j, RGBA, 3); | |
j+=3; | |
} | |
} | |
/** | |
* \fn void img2ppm(Img *img) | |
* \brief Affiche l'image PPM correspondant à la structure Img passée en paramètre sur la sortie standard | |
* | |
* \param img Un pointeur sur la structure Img correspondant aux dimensions et valeurs RGB de l'image PPM raw à afficher. | |
* | |
*/ | |
void img2ppm(Img *img) | |
{ | |
uint32_t j = 0; /*!< Compteur (pour parcourir la mémoire) */ | |
printf("P6\n"); /*!< Nombre magique correspondant au format de l'image */ | |
printf("#bla bla\n"); /*!< Un commentaire optionnel */ | |
printf("%d %d\n", img->largeur, img->hauteur); /*!< Largeur et hauteur de l'image */ | |
printf("255\n"); /*!< La valeur maximale utilisée pour coder chaque composante primaire */ | |
while(j < img->largeur*img->hauteur*3){ /*!< Remplissage avec les données binaires de l'image */ | |
fwrite(img->addr+j, 3, 1, stdout); | |
j+=3; | |
} | |
} | |
/** | |
* \fn int main (void) | |
* \brief Entrée du programme de test. | |
* | |
* \return EXIT_SUCCESS - Arrêt normal du programme. | |
*/ | |
int main(void) | |
{ | |
Img ppm; | |
readImg(&ppm, "../img0.rgb32"); | |
img2ppm(&ppm); | |
free(ppm.addr); | |
return EXIT_SUCCESS; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment