#include <stdlib.h>
#include <stdio.h>
#define bufsize 1024
struct symbol
{
unsigned char znak;
float czest;
};
struct znak
{
unsigned char symbol;
unsigned char dlkodu;
unsigned int kod;
};
int WyznaczCzestosci(char *nazwa, struct symbol *t)
{
FILE *plik;
int n;
int lwz=0;
unsigned char buf[bufsize];
plik=fopen(nazwa,"rb");
if (!plik)
{
printf("Nie mozna otworzyc pliku!");
return 1;
} else
{
do
{
n=fread(buf, sizeof(unsigned char), bufsize, plik);
int i=0;
for ( ;i<n;i++)
(t+buf[i])->czest++;
lwz+=n;
}while(n>0);
fclose(plik);
int k=0;
for (;k<27;k++)
(t+k)->czest/=(float)lwz;
return 0;
}
}
int porownaj(const void *op1,const void *op2)
{
const struct symbol *ptr1=(const struct symbol*)op1;
const struct symbol *ptr2=(const struct symbol*)op2;
if (ptr1->czest==ptr2->czest)
return 0;
else
{
if (ptr1->czest > ptr2->czest)
return 1;
else
return -1;
}
}
void wyswietl (struct symbol *t)
{
int i=0;
for (; i<256; i++)
printf("%c -> %f \n",(t+i)->znak,(t+i)->czest);
}
int ZapisDoPliku(char *nazwa, struct symbol *t)
{
FILE *plik;
if(!(plik=fopen(nazwa,"wb")))
{
printf("Nie mozna otworzyc pliku");
return 0;
} else
{
int i=0;
for(; i<27; i++)
{
if(t->czest!=0)
fprintf(plik,"%c->%8.8f\n",t->znak,t->czest);
}
fclose(plik);
} return 1;
}
int UtworzTabliceKodowa(unsigned short *rozmiar, struct znak **t,char *sciezka)
{
FILE *plik2;
if ((plik2=fopen(sciezka,"rb"))==NULL)
{
printf("Nie udalo sie otworzyc pliku");
return 0;
}
else
{
fread(rozmiar, sizeof (unsigned short),1,plik2);
*t=(struct znak *)calloc(*rozmiar,sizeof (struct znak));
int i=0;
for (;i<*rozmiar;i++)
{
fread(&(*t+i)->symbol, sizeof(unsigned char),1,plik2);
fread(&(*t+i)->dlkodu, sizeof(unsigned char),1,plik2);
fread(&(*t+i)->kod,sizeof(unsigned int),1,plik2);
}
return 1;
}
}
int Kompresuj (char *nazwaplikzr, char *nazwaplikwyn, struct znak **t, unsigned short rozmiar)
{
unsigned int tmp, paczka=0;
int wolne=32;
int dk;
unsigned char litera;
FILE *plikz;
FILE *plikw;
plikz=fopen(nazwaplikzr,"rb");
plikw=fopen(nazwaplikwyn,"wb");
paczka=0;
while(fread(&litera,sizeof(unsigned char),1,plikz))
{
int i=0;
for(;i<rozmiar;i++)
{
if ((*t+i)->symbol == litera)
{
tmp=(*t+i)->kod;
dk=(*t+i)->dlkodu;
break;
}
}
if(wolne>=dk)
{
tmp<<=(wolne-dk);
paczka^=tmp;
wolne-=dk;
if(wolne==0)
{
fwrite(&paczka,sizeof(unsigned int),1,plikw);
paczka=0;
wolne=32;
}
}
else {
paczka^=(tmp>>(dk-wolne));
fwrite(&paczka,sizeof(unsigned int),1,plikw);
paczka=0;
tmp<<=32+wolne-dk;
paczka^=tmp;
wolne=32+wolne-dk;
}
}
if(paczka!=0){
fwrite(&paczka,sizeof(unsigned int),1,plikw);}
fclose(plikz);
fclose(plikw);
return 0;
}
int Dekompresuj(char *nazwaplikzr,char *nazwaplikwyn,struct znak *t){
FILE *plikz,*plikw;
unsigned int tmp, paczka1=0,paczka2=0;
int wolne=32;
if((plikz=fopen(nazwaplikzr,"rb"))==NULL){
printf("Brak pliku do zdekompresowania");
return 1;
}
plikw=fopen(nazwaplikwyn,"w+");
fread(&paczka1,sizeof(unsigned int),1,plikz);
if(paczka1==0){
printf("Plik pusty\n");
return 1;
};
fread(&paczka2,sizeof(unsigned int),1,plikz);
while(paczka1!=0){
int i=-1;
do{
i++;
tmp=paczka1;
tmp>>=32-(t+i)->dlkodu;
}
while (tmp!=(t+i)->kod);
fwrite(&(t+i)->symbol,sizeof(unsigned char),1,plikw);
paczka1<<=(t+i)->dlkodu;
if(wolne>=(t+i)->dlkodu){
tmp=paczka2;
wolne=wolne-(t+i)->dlkodu;
tmp>>=32-(t+i)->dlkodu;
paczka1|=tmp;
paczka2<<=(t+i)->dlkodu;
}
else if((wolne<(t+i)->dlkodu)&&!feof(plikz)){
tmp=paczka2;
tmp>>=32-wolne;
wolne=(t+i)->dlkodu-wolne;
tmp<<=wolne;
paczka1|=tmp;
fread(&paczka2,sizeof(unsigned int),1,plikz);
wolne=32-wolne;
if(!feof(plikz)){
tmp=paczka2;
tmp>>=wolne;
paczka1|=tmp;
paczka2<<=32-wolne;
}
}
}
fclose(plikz);
fclose(plikw);
return 0;
}
int main(int argc, char *argv[])
{
unsigned short rozmiar;
struct znak *tabkod;
struct symbol tab[256];
WyznaczCzestosci(argv[2],tab);
wyswietl(tab);
UtworzTabliceKodowa(&rozmiar, &tabkod, argv[1]);
if(*argv[4]==107)
Kompresuj(argv[2], argv[3], &tabkod, rozmiar);
else if (*argv[4]==100) Dekompresuj(argv[2], argv[3], tabkod);
else printf("zle wywolanie");
int i=0;
for(;i<rozmiar;i++)
printf("%c - %d - %x\n",tabkod[i].symbol,tabkod[i].dlkodu,tabkod[i].kod);
return 0;
}