#include #include #include using namespace std; struct element_zrodla { int symbol; int frequency; }; struct element_zrodla model[256]; int licznik_symboli = 0; int nazwa_pliku_Huffman(char *nazwa_pliku, char *rozszerzenie, char *nazwa_pliku_z_nowym_rozszerzeniem) { int i = 0; int n = 0; for (i = 0; i<35; i++) { nazwa_pliku_z_nowym_rozszerzeniem[i] = 0; } while ((nazwa_pliku[n] != 46) && (nazwa_pliku[n] != '')) { n++; } for (i = 0; i0) { model[n].symbol = model_pelny[i].symbol; model[n].frequency = model_pelny[i].frequency; n++; } } return n; } int oblicz_model_Huffman(char *nazwa_pliku, char *nazwa_pliku_model, char *nazwa_pliku_wynik, struct element_zrodla model[]) { int liczba_znakow = 0; int n = 0; unsigned char BUFOR_WEJSCIOWY[1000]; struct element_zrodla model_pelny[256]; for(int i = 0; i < 256; i++) { model_pelny[i].symbol = i; model_pelny[i].frequency = 0; } FILE *plik; plik = fopen(nazwa_pliku,"rb"); if(plik == NULL) { cout <<"Nie udalo sie otworzyc pliku zrodlowego"<frequency) == (p2->frequency)) return 0; else if ((p1->frequency)<(p2->frequency)) return 1; else return -1; } int posortuj_model_Huffmana(struct element_zrodla model[], int liczba_elementow, char*plik_model_posortowany) { qsort(model, liczba_elementow, sizeof(struct element_zrodla), funkcja_porownujaca); FILE *plik; plik = fopen(plik_model_posortowany, "wb"); if (plik == NULL) { cout << "Blad w trakcie otwierania pliku do zapisu posortowanego modelu" <0) { tablica_kodowania[liczba_znakow].symbol = kod_znaku; tablica_kodowania[liczba_znakow].liczba_bitow = dlugosc_slowa; for (int i = 0; i<4; i++) { tablica_kodowania[liczba_znakow].slowo[i] = bajty[i]; } liczba_znakow++; } } fclose(plik); printf("Odczytano %d znakow z pliku ze zmodyfikowana tablica kodowanian", liczba_znakow); } return liczba_znakow; } int kompresja_Huffman(struct element_tablicy tablica_kodowania[], char* plik_wejsciowy, char* plik_wynikowy, int liczba_elementow_tablicy) { int n; int liczba_bitow_znaku; int suma_bitow=0; int kursor; int kursor_out; int liczba_pozostalych; int liczba_wolne_bity; int liczba_zak_symboli; int numer_slowa; int numer_bajtu; int dopisek; unsigned char maska; unsigned char znak; unsigned char bufor_wejsciowy[1000]; unsigned char bufor_wyjsciowy[1000]; unsigned char slowo_znaku[4]; unsigned char bajt_out; FILE *plik; FILE *plik_out; plik_out = fopen(plik_wynikowy, "a+"); if (plik_out == NULL) { printf("Nie udalo sie otworzyc pliku wynikowegon"); exit(0); } plik = fopen(plik_wejsciowy, "rb"); if (plik == NULL) { printf("Nie udalo sie otworzyc pliku wejsciowegon"); exit(0); } kursor_out = 0; numer_slowa = 0; numer_bajtu = 0; bajt_out = 0; liczba_zak_symboli = 0; while (n = fread(bufor_wejsciowy, sizeof(unsigned char),1000, plik)) { for (int i = 0; i < n; i++) { znak = bufor_wejsciowy[i]; for (int j = 0; j < liczba_elementow_tablicy; j++) { if (znak == tablica_kodowania[j].symbol) { for (int k = 0; k < 4; k++) { slowo_znaku[k] = tablica_kodowania[j].slowo[k]; } liczba_bitow_znaku = tablica_kodowania[j].liczba_bitow; suma_bitow = suma_bitow + liczba_bitow_znaku; kursor = 0; numer_slowa = 0; break; } } while (liczba_bitow_znaku > 0) { liczba_pozostalych = 8 - kursor; if (liczba_pozostalych > liczba_bitow_znaku) { liczba_pozostalych = liczba_bitow_znaku; } liczba_wolne_bity = 8 - kursor_out; if (liczba_pozostalych < liczba_wolne_bity) { liczba_wolne_bity = liczba_pozostalych; } maska = ((255 >> kursor)&(255 << (8 - (kursor + liczba_wolne_bity)))); dopisek = slowo_znaku[numer_slowa] & maska; dopisek = dopisek << kursor; dopisek = dopisek >> kursor_out; bajt_out = bajt_out | dopisek; kursor_out += liczba_wolne_bity; liczba_bitow_znaku -= liczba_wolne_bity; kursor += liczba_wolne_bity; liczba_pozostalych -= liczba_wolne_bity; if (liczba_pozostalych == 0) { numer_slowa++; kursor = 0; if (liczba_bitow_znaku >= 8) { liczba_pozostalych = 8; } else { liczba_pozostalych = liczba_bitow_znaku; } } if (kursor_out == 8) { fwrite(&bajt_out, sizeof(unsigned char), 1, plik_out); numer_bajtu++; kursor_out = 0; bajt_out = 0; } } liczba_zak_symboli++; } } printf("Bajt wyjsciowy numer %d kod hec %x n", numer_bajtu, bajt_out); fwrite(&bajt_out, sizeof(unsigned char), 1, plik_out); printf("Liczba zakodowanych znakow pliku kompresowego: %dn", liczba_zak_symboli); printf("Liczba bajtow w pliku skompresowanym: %dn", numer_bajtu + 1); printf("Wskaznik upakowania: %5.1f procentn", 100 * (float)(numer_bajtu + 1) / (float)liczba_zak_symboli); fclose(plik); fclose(plik_out); return suma_bitow; } int dekompresja_Huffman(char *nazwa_pliku_skom, char *nazwa_pliku_dekom, char *nazwa_pliku_tree, struct galaz_drzewa drzewo_kodowania[]) { int n; int m; int ojciec; int potomek1; int potomek2; int ilosc_symboli; int rozmiar_drzewa; int licznik_drzewa; int suma_symboli; int suma_bitow; unsigned char bajt_wejsciowy; unsigned char bajt_wyjsciowy; unsigned char maska = 128; unsigned char bit; FILE *plik_dek = NULL; plik_dek = fopen(nazwa_pliku_dekom, "wb"); if(plik_dek == NULL) { printf("nBlad w trakcie otwierania pliku zdekodowanego do zapisun"); exit(0); } FILE *plik_tree = NULL; plik_tree = fopen(nazwa_pliku_tree, "rb"); if(plik_tree == NULL) { printf("nBlad w trakcie otwierania pliku z drzewem do odczytun"); exit(0); } FILE *plik = NULL; plik = fopen(nazwa_pliku_skom, "rb"); if(plik == NULL) { printf("nBlad w trakcie otwierania zakodowanego plikun"); exit(0); } else { fscanf(plik_tree, "%dn %dn", &ilosc_symboli, &rozmiar_drzewa); licznik_drzewa = 0; for(int i = 0; i < rozmiar_drzewa; i++) { fscanf(plik_tree, "%d %d %dn", &ojciec, &potomek1, &potomek2); drzewo_kodowania[licznik_drzewa].ojciec = ojciec; drzewo_kodowania[licznik_drzewa].potomek1 = potomek1; drzewo_kodowania[licznik_drzewa].potomek2 = potomek2; licznik_drzewa++; } suma_symboli = 0; suma_bitow = 0; ojciec = drzewo_kodowania[rozmiar_drzewa - 1].ojciec; potomek1 = drzewo_kodowania[rozmiar_drzewa - 1].potomek1; potomek2 = drzewo_kodowania[rozmiar_drzewa - 1].potomek2; while(suma_symboli < ilosc_symboli) { n = fread(&bajt_wejsciowy, sizeof(unsigned char), 1, plik); if(n == 1) { for(int j = 0; j < 8; j++) { bit = bajt_wejsciowy&maska; bajt_wejsciowy = bajt_wejsciowy<<1; suma_bitow++; if(bit) { ojciec = potomek1; } else { ojciec = potomek2; } if(ojciec < 256) { bajt_wyjsciowy = ojciec; fwrite(&bajt_wyjsciowy, sizeof(unsigned char), 1, plik_dek); suma_symboli++; licznik_drzewa = rozmiar_drzewa - 1; ojciec = drzewo_kodowania[rozmiar_drzewa - 1].ojciec; potomek1 = drzewo_kodowania[rozmiar_drzewa - 1].potomek1; potomek2 = drzewo_kodowania[rozmiar_drzewa - 1].potomek2; if(suma_symboli == ilosc_symboli) { break; } } else { m = rozmiar_drzewa - 1; while(m >= 0) { if(drzewo_kodowania[m].ojciec == ojciec) { licznik_drzewa = m; m = -1; } m = m - 1; } potomek1 = drzewo_kodowania[licznik_drzewa].potomek1; potomek2 = drzewo_kodowania[licznik_drzewa].potomek2; } } } } printf("nLiczba odczytanych bitow: %d, liczba zdekodowanych symboli %d.n", suma_bitow, suma_symboli); fclose(plik); fclose(plik_dek); fclose(plik_tree); return(suma_symboli); } } int main() { int wybor; char znak; char nazwa_pliku[30]; char nazwa_pliku_modelu[35]; char nazwa_pliku_mod_modelu[35]; char nazwa_pliku_sort[35]; char nazwa_pliku_drzewo[35]; char nazwa_pliku_tablicy[35]; char nazwa_pliku_mod_tablicy[35]; char nazwa_pliku_wynik[35]; char nazwa_pliku_dekom[35]; char rozszerzenie_modelu[] = "model"; char rozszerzenie_mod_modelu[] = "modmodel"; char rozszerzenie_sort[] = "sort"; char rozszerzenie_drzewo[] = "tree"; char rozszerzenie_tablicy[] = "tab"; char rozszerzenie_mod_tablicy[] = "modtab"; char rozszerzenie_wynik[] = "huff"; char rozszerzenie_dekom[] = "dek.txt"; int liczba_elementow_tablicy = 0; cout << "Teoria informacji i kodowania " <> wybor; if(wybor == 1) { cout << "Podaj nazwe pliku do kompresji wraz z rozszerzeniem: " ; scanf("%s", &nazwa_pliku); nazwa_pliku_Huffman(nazwa_pliku, rozszerzenie_modelu, nazwa_pliku_modelu); printf("nNazwa pliku z modelem: %sn", nazwa_pliku_modelu); nazwa_pliku_Huffman(nazwa_pliku, rozszerzenie_sort, nazwa_pliku_sort); printf("Nazwa pliku z posortowanym modelem: %sn", nazwa_pliku_sort); nazwa_pliku_Huffman(nazwa_pliku, rozszerzenie_mod_modelu, nazwa_pliku_mod_modelu); printf("Nazwa pliku ze zmod. modelem: %sn", nazwa_pliku_mod_modelu); nazwa_pliku_Huffman(nazwa_pliku, rozszerzenie_drzewo, nazwa_pliku_drzewo); printf("Nazwa pliku z drzewem kodowania: %sn", nazwa_pliku_drzewo); nazwa_pliku_Huffman(nazwa_pliku, rozszerzenie_tablicy, nazwa_pliku_tablicy); printf("Nazwa pliku z tablica kodowania: %sn", nazwa_pliku_tablicy); nazwa_pliku_Huffman(nazwa_pliku, rozszerzenie_mod_tablicy, nazwa_pliku_mod_tablicy); printf("Nazwa pliku ze zmod. tablica kodowania: %sn", nazwa_pliku_mod_tablicy); nazwa_pliku_Huffman(nazwa_pliku, rozszerzenie_wynik, nazwa_pliku_wynik); printf("Nazwa pliku wynikowego: %sn", nazwa_pliku_wynik); oblicz_model_Huffman(nazwa_pliku, nazwa_pliku_modelu, nazwa_pliku_drzewo, model); posortuj_model_Huffmana(model, licznik_symboli, nazwa_pliku_sort); utworz_drzewo(model, drzewo_kodowania, licznik_symboli, nazwa_pliku_drzewo, nazwa_pliku_mod_modelu); utworz_tablice_kodowania(drzewo_kodowania, licznik_symboli, tablica_kodowania, nazwa_pliku_tablicy, nazwa_pliku_mod_tablicy); odczytaj_tablice_kodowania(tablica_kodowania, nazwa_pliku_mod_tablicy); kompresja_Huffman(tablica_kodowania, nazwa_pliku, nazwa_pliku_wynik, licznik_symboli); cout <