Skip to content

Instantly share code, notes, and snippets.

@yfe404
Created December 30, 2013 12:58
Show Gist options
  • Save yfe404/8181833 to your computer and use it in GitHub Desktop.
Save yfe404/8181833 to your computer and use it in GitHub Desktop.
Convert non standard format RGB32 to standard format PPM raw
/**
* \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