Compression bz2 (mieux que zlib) en c.

Description

Un simple petit code qui sert d'interface avec la libbz2, qui comme chacun sait compresse un peu mieux que la zlib.
C est une sorte de front-end, qui permet de compresser d'un fichier a la memoire ou d'un fichier a un fichier et pareil pour la decompression.
Les tests d'erreurs sont en principe tous fait, et le code est commente donc en principe pas de soucis.
C'est du C compile avec gcc sous Linux, mais il n'y a aucune raison que ca ne marche pas sous windows.

Source / Exemple :


/* bzcompress.c : compression/decompression bz2 (mieux que zlib)

  • compile sous Linux, necessite la libbz2. Ce programme n'utilise pas de fonctions
  • specifiques Linux, il devrait donc marcher sous windows.
  • gcc -lbz2 bzcompress.c -o bzcompress
*
  • (C) Metaldwarf 2004
  • /
#include <stdio.h> #include <bzlib.h> #define DEFAULT_BLOCK_SIZE 100 // taille des blocs par defaut en octets /* file : fichier de destination data : donnees a compresser len : taille des donnes retourne 0->succes -1->echec
  • /
int compress_to_file(char *file, char *data, int len) { FILE *fd; BZFILE *bh; int bzerr; int in, out; int i; if(!(fd = fopen(file,"w"))) return -1; // probleme IO bh = BZ2_bzWriteOpen(&bzerr, fd, 9, 0, 30); // dans l'ordre : code d'erreur, fichier de sortie, parametre memoire, // verbosite (0-4), facteur pour le compression (1-250) if(bzerr != BZ_OK) // onquitte sur une erreur { fclose(fd); BZ2_bzWriteClose(&bzerr,bh,1,&in,&out); // dans l'ordre : code d'erreur, flux BZ2, action a effectuer avant de quitter (1->rien 0->ecrire les buf internes // avant de quitter), taille des donnees avant compression, taille apres compression return -1; } for(i=0;i<len;i++) // boucle d ecriture dans le flux { bzerr=BZ_OK; BZ2_bzWrite(&bzerr,bh,&(data[i]),1); // dans l'ordre : code d'erreur, flux BZ2, pointeur sur les donnees, taille des donnees if(bzerr=BZ_IO_ERROR) { BZ2_bzWriteClose(&bzerr,bh,1,&in,&out); fclose(fd); return -1; } } BZ2_bzWriteClose(&bzerr,bh,0,&in,&out); // on a fini donc on ferme!! fclose(fd); if(out >= in) printf("\nAttention : Compression inutile (taille en sortie >= taille en entree)\n"); return 0; } /* fin : fichier a compresser fout: fichier de sortie retourne 0->succes -1->erreur
  • /
int compress_file_to_file(char *fin, char *fout) { FILE *fdin, *fdout; BZFILE *bh; int bzerr; int in, out; char c; if(!((fdin = fopen(fin,"r")) && (fdout = fopen(fout,"w")))) { printf("\nErreur IO!"); return -1; // probleme IO } bh = BZ2_bzWriteOpen(&bzerr, fdout, 9, 0, 30); // dans l'ordre : code d'erreur, fichier de sortie, parametre memoire, // verbosite (0-4), facteur pour le compression (1-250) if(bzerr != BZ_OK) // onquitte sur une erreur { fclose(fdin); fclose(fdout); BZ2_bzWriteClose(&bzerr,bh,1,&in,&out); // dans l'ordre : code d'erreur, flux BZ2, action a effectuer avant de quitter (1->rien 0->ecrire les buf internes // avant de quitter), taille des donnees avant compression, taille apres compression printf("\nErreur d'ouverture du flux!"); return -1; } while(fread(&c,1,1,fdin) == 1) // boucle d ecriture dans le flux { bzerr=BZ_OK; BZ2_bzWrite(&bzerr,bh,&c,1); // dans l'ordre : code d'erreur, flux BZ2, pointeur sur les donnees, taille des donnees if(bzerr==BZ_IO_ERROR) { BZ2_bzWriteClose(&bzerr,bh,1,&in,&out); fclose(fdin); fclose(fdout); printf("\nErreur de compression"); return -1; } } BZ2_bzWriteClose(&bzerr,bh,0,&in,&out); // on a fini donc on ferme!! fclose(fdin); fclose(fdout); if(out >= in) printf("\nAttention : Compression inutile (taille en sortie >= taille en entree)\n"); return 0; } /* filename : fichier a decompresser block_size : taille des blocs a utiliser (pour aider la fonction). Par defaut 100 octets, donc 0->100 size : pointeur sur un int (et pas un tableau), renvoit la taille des donnees lues cette fonction retourne un pointeur sur les donnees lues, NULL en cas d echec
  • /
void * uncompress_from_file(char *filename, int block_size, int *size) { FILE *fd; BZFILE *bh; int bzerr; int size_read; int i=0; char *data = NULL; /* allocation initiale de la memoire */ if(block_size == 0) block_size = DEFAULT_BLOCK_SIZE; if((data = (char *) malloc(block_size)) == NULL) { printf("\nAllocation memoire impossible!\n"); return NULL; } if(!(fd = fopen(filename,"r"))) { printf("\nImpossible de lire le fichier d'nentree!\n"); return NULL; } bh = BZ2_bzReadOpen(&bzerr, fd, 0, 0, NULL, 0); // dans l'ordre : code d'erreur, FILE *, verbosite (0-4) // type d algorithme a utiliser (0->+ de memeoire,- de CPU 1->- de memoire, + de CPU) // les autres e servent a rien quand on commence a lire du debut... if(bzerr != BZ_OK) { BZ2_bzReadClose(&bzerr,bh); fclose(fd); printf("\nOuverture du flux impossible!!"); return NULL; } bzerr = BZ_OK;
  • size = 0;
while(bzerr == BZ_OK) { size_read = BZ2_bzRead(&bzerr, bh, data + (i * block_size),block_size); if(bzerr == BZ_OK) { i++;
  • size += size_read;
if((data = (char *) realloc(data,block_size * (i+1))) == NULL) { BZ2_bzReadClose(&bzerr,bh); fclose(fd); printf("\nRealloc impossible!!"); return NULL; } }
  • size += size_read;
if(bzerr != BZ_STREAM_END) printf("\nProbleme de lecture!\n"); } /*On a fini donc on ferme tout et on redimensionne la zone memoire */ BZ2_bzReadClose(&bzerr,bh); fclose(fd); data = (char *) realloc(data,*size); return (void *) data; } /* fin : fichier a decompresser fout: fichier reslutat block_size : taille des blocs a utiliser retourne 0->succes -1->echec
  • /
int uncompress_from_file_to_file(char *fin, char *fout, int block_size) { FILE *fdin; FILE *fdout; BZFILE *bh; int bzerr; int size_read; char *data = NULL; /* allocation initiale de la memoire */ if(block_size == 0) block_size = DEFAULT_BLOCK_SIZE; if((data = (char *) malloc(block_size)) == NULL) { printf("\nAllocation memoire impossible!\n"); return -1; } if(!((fdin = fopen(fin,"r")) && (fdout = fopen(fout,"w")))) { printf("\nImpossible de lire le fichier d'nentree!\n"); return -1; } bh = BZ2_bzReadOpen(&bzerr, fdin, 0, 0, NULL, 0); // dans l'ordre : code d'erreur, FILE *, verbosite (0-4) // type d algorithme a utiliser (0->+ de memeoire,- de CPU 1->- de memoire, + de CPU) // les autres e servent a rien quand on commence a lire du debut... if(bzerr != BZ_OK) { BZ2_bzReadClose(&bzerr,bh); fclose(fdin); fclose(fdout); printf("\nOuverture du flux impossible!!"); return -1; } bzerr = BZ_OK; while(bzerr == BZ_OK) { size_read = BZ2_bzRead(&bzerr, bh, data,block_size); if((bzerr == BZ_OK) || (bzerr == BZ_STREAM_END)) { fwrite(data,size_read,1,fdout); } else printf("\nProbleme de lecture!\n"); } /* On a fini donc on ferme tout */ BZ2_bzReadClose(&bzerr,bh); fclose(fdin); fclose(fdout); free(data); return 0; } /*exemple tres simple d'utilisation */ int main(int argc, char **argv) { int size; char * data; compress_file_to_file(argv[1],argv[2]); data = (char *) uncompress_from_file_to_file(argv[2],"resultat.c",0); printf("%d",size); data[size -1] = '\0'; printf("%s",data); return 0; }

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.