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
*
#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;
while(bzerr == BZ_OK)
{
size_read = BZ2_bzRead(&bzerr, bh, data + (i * block_size),block_size);
if(bzerr == BZ_OK)
{
i++;
if((data = (char *) realloc(data,block_size * (i+1))) == NULL)
{
BZ2_bzReadClose(&bzerr,bh);
fclose(fd);
printf("\nRealloc impossible!!");
return NULL;
}
}
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;
}
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.