KOMMANDOInternetMatérielsPrestationsNEXTSTEP·OPENSTEPFormationsPartenairesRéférences



[Banniere]


/* Decompression depuis image au format CPII */

/* La compilation ressemble a :
  gcc -O3 -DHAVE_UNISTD_H -DUSE_MMAP -o cpii2rgb cpii2rgb.c -lz
  strip cpii2rgb
*/

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

#define LARGEUR_MIN 1
#define HAUTEUR_MIN 1

#define min(a,b) ((a) < (b) ? (a) : (b))

void developpeCouleurs (char *table);

void afficheUtilisation (const char *application)
{
    fprintf (stderr, "Usage : %s image_compressée x y largeur hauteur [image_RGB]\n", application);
}

int main(int argc, char *argv[])
{
    if ((argc != 6) && (argc != 7))
    {
        afficheUtilisation (argv[0]);
    }
    else
    {
        long xExtraction = atoi (argv[2]),
             yExtraction = atoi (argv[3]),
             largeurExtraction = atoi (argv[4]),
             hauteurExtraction = atoi (argv[5]);

        if (largeurExtraction >= LARGEUR_MIN && hauteurExtraction >= HAUTEUR_MIN)
        {
            static const char *maVersion = ZLIB_VERSION;
            FILE *source,
                 *destination;

            if (zlibVersion ()[0] != maVersion[0]) 
            {
                fprintf (stderr, "Version de librairie zlib inutilisable\n");
                exit (1);
            } 
            else 
            {
                if (strcmp (zlibVersion (), ZLIB_VERSION) != 0) 
                {
                    fprintf (stderr, "Attention : versions différentes de librairies zlib\n");
                }
            }
            if (argc == 7)
            {
                if (! (destination = fopen (argv[6], "wb")))
                {
                    fprintf (stderr, "création %s impossible\n", argv[6]);
                    exit (1);
                }
            }
            else
            {
                destination = stdout;
            }
            if (source = fopen (argv[1], "rb"))
            {
                char signature[8];
                long largeur,
                     hauteur,
                     longueurMaximale;
                char couleurs[256][6];

                if ((fread (signature, sizeof (signature), 1, source) == 1) && (fread (&largeur, sizeof (long), 1, source) == 1) && (fread (&hauteur, sizeof (long), 1, source) == 1) && (fread (&longueurMaximale, sizeof (long), 1, source) == 1) && (fread (couleurs, sizeof (long), 3, source) == 3) && (fread (couleurs, sizeof (long), 256, source) == 256))
                {
                    unsigned long *tableLignes;
                    Byte *donneesCompressees,
                         *donneesDecompressees;

                    if ((xExtraction >= largeur) || (yExtraction >= hauteur))
                    {
                        fprintf (stderr, "zone à extraire en dehors des limites de l'image\n");
                        exit (1);
                    }
                    largeurExtraction = min (largeurExtraction, largeur - xExtraction);
                    hauteurExtraction = min (hauteurExtraction, hauteur - yExtraction);
                    developpeCouleurs ((char *) couleurs);

                    tableLignes = (unsigned long *) malloc ((hauteurExtraction + 1) * sizeof (long));
                    donneesCompressees = (Byte *) malloc (longueurMaximale * sizeof (Byte));
                    donneesDecompressees = (Byte *) malloc (largeur * sizeof (Byte));

                    if (tableLignes == Z_NULL || donneesCompressees == Z_NULL || donneesDecompressees == Z_NULL)
                    {
                        fprintf (stderr, "mémoire insuffisante\n");
                        exit (1);
                    }
                    if (fseek (source, sizeof (signature) + (6 + 256 + yExtraction) * sizeof (long), SEEK_SET) == -1)
                    {
                        fprintf (stderr, "erreur lors du déplacement dans l'index\n");
                        exit (1);
                    }
                    if (fread (tableLignes, sizeof (long), hauteurExtraction + 1, source) == (hauteurExtraction + 1))
                    {
                        if (fseek (source, sizeof (signature) + (6 + 256 + hauteur + 1) * sizeof (long) + tableLignes[0], SEEK_SET) == -1)
                        {
                            fprintf (stderr, "erreur lors du déplacement dans l'index\n");
                            exit (1);
                        }
                        else
                        {
                            long ligne;

                            for (ligne = 0; ligne < hauteurExtraction; ligne++)
                            {
                                long longueurCompressee = tableLignes[ligne + 1] - tableLignes[ligne],
                                     longueurDecompressee = largeur,
                                     numeroPixel;
                                int  erreur;

                                if (fread (donneesCompressees, sizeof (Byte), longueurCompressee, source) != longueurCompressee)
                                {
                                    fprintf (stderr, "données manquantes\n");
                                    exit (1);
                                }
                                if (((erreur = uncompress (donneesDecompressees, &longueurDecompressee, donneesCompressees, longueurCompressee)) != Z_OK) || (longueurDecompressee != largeur))
                                {
                                    fprintf (stderr, "une erreur de décompression est intervenue ligne %d (code %d)\n", ligne + yExtraction, erreur);
                                    exit (1);
                                }
                                for (numeroPixel = xExtraction; numeroPixel < (xExtraction + largeurExtraction); numeroPixel++)
                                {
                                    if (fwrite (&couleurs[donneesDecompressees[numeroPixel]], sizeof (char), 6, destination) != 6)
                                    {
                                        fprintf (stderr, "écriture impossible\n");
                                        exit (1);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        fprintf (stderr, "lecture de l'index des lignes à extraire impossible\n");
                    }
                }
                else
                {
                    fprintf (stderr, "lecture de l'entête impossible\n");
                }
                fclose (source);

                if (destination != stdout)
                {
                    fclose (destination);
                }
            }
            else
            {
                fprintf (stderr, "ouverture %s impossible\n", argv[1]);
            }
        }
        else
        {
            fprintf (stderr, "largeur ou hauteur trop faible pour justifier une extraction (%d pixels au minimum)\n", LARGEUR_MIN);
        }
    }
    exit(0);
    return 0;
}

void developpeCouleurs (char *table)
{
    int  indice;
    long *couleurs = (long *) table;

    for (indice = 255; indice >= 0; indice--)
    {
        long couleur = couleurs[indice];
        char rouge = (couleur >> 16) & 255,
             vert = (couleur >> 8) & 255,
             bleu = couleur & 255;

        table[indice * 6 + 5] = table[indice * 6 + 4] = bleu;
        table[indice * 6 + 3] = table[indice * 6 + 2] = vert;
        table[indice * 6 + 1] = table[indice * 6 + 0] = rouge;
    }
}

[petit logo]

     Chercher sur ce site

Une remarque, une question ou une suggestion ? Merci de nous écrire à info@kommando.com.

KOMMANDO
Siège social : 3, rue Jacques Daguerre · 95370 MONTIGNY lès CORMEILLES
Tél : 33 (0)6 60 60 10 48 · Fax : 33 (0)6 61 60 10 48 · info@kommando.com



KOMMANDOInternetMatérielsPrestationsNEXTSTEP·OPENSTEPFormationsPartenairesRéférences