Code source du fichier src/genbargraphe.c

/*
    Fichier genbargraphe.c
    Auteur Bernard Chardonneau

    Logiciel libre diffusé dans le domaine public.


    Fonction qui génère un bargraphe sous la forme d'une images bmp
*/

#include <stdio.h>
#include <stdlib.h>

// constantes
#include "bargraphe.h"
#include "entete-bmp.h"


// palette des couleurs (violet, bleu vert, vert, jaune légèrement orangé, rouge)
static long palette [] = {0x6000FF, 0x0060FF, 0x00E000, 0xFFE000, 0xFF0000};


// création d'un barregraphe bmp

int cree_bargraphe (char *fichier, float *taux)
{
    // position du dernier pixel pour chaque couleur dans la ligne
    int pix_dose [coul_bgraph];

    char *ligne;    // une ligne de l'image (2 pixels par octet)
    int  lg_ligne;  // le nombre d'octets qu'elle nécessite
    int  manque;    // pour compléter la ligne à un multiple de 4 octets
    int  pos_ligne; // position dans la ligne en cous de remplissage

    int  fin_coul;  // pour compter par groupe de 2 pixels
    float coefpix;  // nombre de pixels pour 1 %
    int  couleur;   // numéro de la couleur qu'on rajoute
    char d_pix;     // octet avec les valeurs de 2 couleurs consécutives
    int  num_ligne; // compteur de lignes
    FILE *descfic;  // descripteur du fichier bmp


    // calculer le nombre d'octets de la ligne mémorisée
    lg_ligne = larg_bgraph / 2;

    manque = lg_ligne % 4;

    if (manque)
        lg_ligne = lg_ligne + 4 - manque;

    // allouer la mémoire pour une ligne de l'image
    ligne = malloc (lg_ligne);

    // calcul du nombre de pixels pour 1 % dans le bargraphe
    coefpix = larg_bgraph / 100.0;

    // dernière couleur correspondant à "non vacciné"
    couleur = coul_bgraph - 1;

    // le dernier pixel pour cette couleur correspondra à 100 %
    pix_dose [couleur] = larg_bgraph;

    // tant qu'on n'a pas traité toutes les couleurs du bargraphe
    while (couleur)
    {
        // remonter d'une couleur (ce qui revient à traiter la dose suivante)
        couleur --;

        // dernier pixel de la couleur pour la dose concernée
        pix_dose [couleur] = (coefpix * taux [couleur]) + 0.5;
    }

    // initialisations
    couleur   = 0;  // couleur de la dernière dose
    pos_ligne = 0;  // début de la ligne

    // tant qu'on n'a pas traité toute les couleurs du bargraphe
    while (couleur < coul_bgraph)
    {
        // code de couleur pour 2 pixels consécutifs de la couleur courante
        d_pix = couleur * 0x11;

        // position du dernier couple de pixels de cette couleur
        fin_coul = pix_dose [couleur] / 2;

        // tant qu'on n'a pas traité tous les couples de pixels de cette couleur
        while (pos_ligne < fin_coul)
            // colorer 2 pixels dans la ligne
            ligne [pos_ligne ++] = d_pix;

        // si le dernier pixel de cette couleur a une valeur impaire
        if (pix_dose [couleur] & 1)
        {
            // sauter les couleurs correspondant au même nombre de pixels
            do
                couleur ++;
            while (pix_dose [couleur - 1] == pix_dose [couleur]);

            // colorer ce pixels et le suivant dans les bonnes couleurs
            ligne [pos_ligne ++] = (d_pix & 0xF0) | couleur;
        }
        // sinon
        else
            // passer à la couleur correspondant à la dose précédente
            couleur ++;
    }

    // initialiser la fin de ligne
    while (pos_ligne < lg_ligne)
        ligne [pos_ligne ++] = 0;

    // c'est parti pour générer le fichier image

    // ouvrir le fichier en écriture
    descfic = fopen (fichier, "w");

    // si l'ouverture s'est bien passée
    if (descfic)
    {
        // copier l'entête bmp
        fwrite (entete, sizeof (entete), 1, descfic);

        // copier la palette
        fwrite (palette, sizeof (palette), 1, descfic);

        // générer les lignes de l'image
        for (num_ligne = 0; num_ligne < haut_bgraph; num_ligne++)
            fwrite (ligne, lg_ligne, 1, descfic);

        // le fichier bmp est prêt
        fclose (descfic);
    }
    // sinon
    else
        // message d'erreur
        fprintf (stderr, "Impossible de créer le fichier %s\n", fichier);
}