5 votes

En utilisant zlib pour créer un fichier gzip en utilisant l'exemple zpipe.c

Tout le monde,

Je suis en train d'essayer de faire fonctionner la démonstration de zpipe en utilisant dev-c++ où j'ai importé tout le code zlib et j'utilise le zpipe.c comme exemple. Tout compile et fonctionne. Si j'essaie de créer un fichier gzip en utilisant l'appel commenté à deflateInit2, il se crée sans erreurs, mais est corrompu lors du dézippage avec 7zip. Si j'utilise les en-têtes standard de zlib pour créer le fichier, lorsque j'utilise l'appel correspondant à inflate, cela me renvoie -3/Z_DATA_ERROR indiquant que mes données de compression sont corrompues. Tout pointe vers une erreur dans la fonction def, mais c'est pratiquement exactement l'exemple.

Des idées ?? Merci beaucoup d'avance !

int main(int argc, char **argv)
{
     int ret;
     FILE *source;
     FILE *zip;
     FILE *zipped;
     FILE *back;

     source = fopen ("C:\\Users\\schmoudm\\Pictures\\caela.jpg", "r");
     zip = fopen ("C:\\Core\\RD\\test.gz", "w");

     printf ("appel def \n");
     ret = def(source, zip, Z_DEFAULT_COMPRESSION);
     printf("retour def : %i \n", ret);
     fclose(source);
     fclose(zip);

     if (ret == 0) {
        printf ("mise en place de inf \n");
        zipped = fopen ("C:\\Core\\RD\\test.gz", "r");
        back = fopen ("C:\\Core\\RD\\zlibout.txt", "w");
        printf ("appel inf \n");
        ret = inf(zipped, back);
        printf("retour inf : %i \n", ret);
        zerr(ret);
     }

    fclose(source);
    fclose(zip);

    printf("TERMINÉ !");
    system("PAUSE");
    return 0;
}

int def(FILE *source, FILE *dest, int level)
{
    int ret, flush;
    unsigned have;
    z_stream strm;
    unsigned char in[CHUNK];
    unsigned char out[CHUNK];

    /* allouer l'état de compression */
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;

    ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
    //ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY);
    if (ret != Z_OK)
        return ret;

    /* compresser jusqu'à la fin du fichier */
    do {
        strm.avail_in = fread(in, 1, CHUNK, source);
        printf("disponible en : %u \n", strm.avail_in);
        if (ferror(source)) {
            (void)deflateEnd(&strm);
            return Z_ERRNO;
        }
        flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
        strm.next_in = in;

        /* exécuter deflate() sur l'entrée jusqu'à ce que le tampon de sortie ne soit pas plein, terminer
           la compression si tout le fichier source a été lu */
        do {
            strm.avail_out = CHUNK;
            strm.next_out = out;
            ret = deflate(&strm, flush);    /* pas de mauvaise valeur de retour */
            assert(ret != Z_STREAM_ERROR);  /* l'état n'est pas corrompu */
            have = CHUNK - strm.avail_out;
            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
                (void)deflateEnd(&strm);
                return Z_ERRNO;
            }
        } while (strm.avail_out == 0);
        assert(strm.avail_in == 0);     /* toute l'entrée sera utilisée */

        /* terminé lorsque les dernières données du fichier sont traitées */
    } while (flush != Z_FINISH);
    assert(ret == Z_STREAM_END);        /* le flux sera complet */

    /* nettoyer et retourner */
    (void)deflateEnd(&strm);
    return Z_OK;
}

3voto

Mark Adler Points 15178

mais c'est à peu près exactement l'exemple.

Hélas, vous avez omis une partie critique de zpipe.c.

#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
#  include 
#  include 
#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#else
#  define SET_BINARY_MODE(file)
#endif

et

/* éviter les conversions de fin de ligne */
SET_BINARY_MODE(stdin);
SET_BINARY_MODE(stdout);

Ainsi, dans votre code, vous devez faire SET_BINARY_MODE(source) et SET_BINARY_MODE(zip).

Ou vous devez utiliser l'option "b" dans les deux fopen().

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X