Facebook
From Whipped Eider, 5 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 243
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define kropka 46
  4. #define BUFOR 1000
  5. #define MAX_PATH 256
  6. //struktura zawierajaca kod znaku oraz iolos jego wystapien
  7.  
  8. struct element_zrodla {
  9.     int indeks_znaku;
  10.     int ilosc_wystapien;
  11. };
  12. //struktura o rozmiarze 256
  13. struct element_zrodla model[256];
  14.  
  15. //licznik elementów zródla
  16. int  licznik_symboli = 0;
  17.  
  18. //funkcja zmieniajaca nazwe pliku
  19. int stworz_nazwe_pliku(char *nazwa_pliku, char *rozszerzenie, char *nazwa_pliku_z_nowym_rozszerzeniem) {
  20.     int i = 0;  //zmienna pomocnicza
  21.     int n = 0;  //zmienna pomocnicza
  22.     while((nazwa_pliku[n]!= kropka)&&(nazwa_pliku[n]!= '\0'))
  23.         n++;
  24.     for(i = 0; i<n;i++)
  25.         nazwa_pliku_z_nowym_rozszerzeniem[i] = nazwa_pliku[i];
  26.    
  27.         nazwa_pliku_z_nowym_rozszerzeniem[i] = kropka;
  28.     n=0;
  29.     i++;
  30.  
  31.     while(rozszerzenie[n] != '\0'){
  32.         nazwa_pliku_z_nowym_rozszerzeniem[i] = rozszerzenie[n];
  33.         i++;
  34.         n++;
  35.     }
  36.  
  37.     nazwa_pliku_z_nowym_rozszerzeniem[i] = 0;
  38.     return 0;
  39. }
  40.  
  41. int utworz_model_niepelny_Huffman(struct element_zrodla model[], struct element_zrodla model_pelny[256]) {
  42.     int n=0;
  43.     int i=0;
  44.     for(i = 0; i < 256; i++){
  45.         if(model_pelny[i].ilosc_wystapien > 0){
  46.             model[n].indeks_znaku = model_pelny[i].indeks_znaku;
  47.             model[n].ilosc_wystapien = model_pelny[i].ilosc_wystapien;
  48.             n++;
  49.         }
  50.     }
  51.     return 0;
  52. }
  53.  
  54. //metoda obliczajaca ilosci wystapien poszczegolnych znakow
  55.  
  56. int policz_symbole(char *nazwa_pliku, char *nazwa_pliku_model, char *nazwa_pliku_wynik, struct element_zrodla model[])
  57. {
  58. int liczba_znakow = 0; //zmienne pomocnicze
  59. int n=0;
  60. int i=0;
  61. int j=0;
  62. int k=0;
  63. unsigned char BUFOR_WEDSCIOWY[BUFOR]; //bufor wykorzystywany przy odczycie danych z pliku
  64. struct element_zrodla model_pelny[256]; //pelny model zrodla
  65. for(i = 0; i < 256; i++) //petla po pelnym modelu zrodla
  66. {
  67.     model_pelny[i].indeks_znaku = i; // przypisanie kodu znaku
  68.     model_pelny[i].ilosc_wystapien = 0; // ustawienie ilosci wystapien na 0
  69. }
  70.  
  71. FILE *plik; //wskaznik do pliku
  72. plik = fopen(nazwa_pliku, "rb"); //otwarcie pliku w trybie "read-binary"
  73. if (plik == NULL) //jezeli nie udalo sie otworzyc pliku do odczytu
  74.     printf ("Nie udalo sie otworzyc pliku zrodlowego\n");
  75. else //jezeli udalo sie otworzyc plik
  76. {
  77.     printf("Odczytuje plik zrodlowy\n");
  78.     while (n = fread(BUFOR_WEDSCIOWY, sizeof(unsigned char), BUFOR, plik)) //dopoki sa odczytywane znaki pliku
  79.         {
  80.             for(j = 0; j < n; j++) //petla od 0 do n
  81.             {
  82.                 model_pelny[BUFOR_WEDSCIOWY[j]].ilosc_wystapien++; //zwiekszenie ilosci wystapien odczytanego znaku z pliku
  83.             }
  84.         liczba_znakow += n; //zwiekszenie liczby znakow w pliku
  85.         }  
  86.     printf("W pliku wejsciowym bylo %d znakow\n", liczba_znakow);
  87.     fclose(plik); //zamkniecie pliku
  88.     plik = fopen(nazwa_pliku_wynik, wb); //otwarcie pliku do zapisu binarnego (plik z iloscia znakow)
  89.     if(plik == NULL) //jezeli nie udalo sie otworzyc pliku
  90.     {
  91.         printf("Nie mozna otworzyc pliku %d", nazwa_pliku_wynik);
  92.         exit(EXIT_FAILURE);
  93.     }
  94.     else //jezeli udalo sie otworzyc plik
  95.     {
  96.         fprintf(plik,"%d \n", liczba_znakow); //wypisanie ilosci znakow do pliku
  97.         fclose(plik); //zamkniecie pliku
  98.     }
  99.     licznik_symboli = utworz_model_niepelny_Huffman(model, model_pelny); //wywolanie metody wyznaczajacej niepelny model Huffmana
  100.     plik = fopen(nazwa_pliku_model, "wb"); //otwarcie pliku do zapisu binarnego
  101.     if(plik == NULL) //jezeli nie udalo sie otworzyc pliku
  102.     {
  103.         printf ("Nie udalo sie otworzyc pliku %d\n", nazwa_pliku_model);
  104.         exit(EXIT_FAILURE);
  105.     }
  106.     else //jezeli udalo sie otworzyc plik
  107.     {
  108.         for(k = 0; k < licznik_symboli; k++) //petla po ilosci symboli odczytanych z pliku
  109.             fprintf(plik, "%d %d \n", model[k].indeks_znaku, model[k].ilosc_wystapien); //wypisanie kodu znaku i ilosci wystapien do pliku
  110.             fclose(plik); //zamkniecie pliku
  111.     }
  112. }
  113. return 0;
  114. }
  115.  
  116. //funckja porównujaca wartosci modelu, wykorzystywana przez quicksort
  117. int funkcja_porownujaca(const void element1, const void element2)
  118. {
  119.     const struct element_zrodla p1=(const struct element_zrodla) element1;
  120.     const struct element_zrodla p2=(const struct element_zrodla) element2;
  121.     if((p1->ilosc_wystapien)==(p2->ilosc_wystapien))
  122.         return 1;
  123.     else if((p1->ilosc_wystapien)<(p2->ilosc_wystapien))
  124.         return 1;
  125.     else
  126.         return -1;
  127. }
  128.  
  129. //funkcja sotrujaca model zródla informacji i zapisujaca go do pliku
  130. int posortuj_symbole(struct element_zrodla model[], int licza_elementow, char* plik_model_posortowany)
  131. {
  132.         int i=0;
  133.     //wywolanie funkcji sortujacej
  134.     qsort(model, liczba_elementow, sizeof(struct element_zrodla), funckja_porownujaca);
  135.     //wskaznik na plik
  136.     FILE *plik;
  137.     //otwarcie pliku
  138.     plik=fopen(plik_model_posortowany,"wb");
  139.     //jezeli nie udalo sie otworzyc pliku do zapisu binarnego
  140.     if(plik==NULL)
  141.     {
  142.         printf("Blad w trakcie otwierania plku do zapisu posortowanego modelu\n");
  143.         exit(EXIT_FAILURE);
  144.     }
  145.     else
  146.     {
  147.         //petla po ilosci elementów w zródle informacji
  148.         for(i=0; i<liczba_elementow; i++)
  149.         {
  150.             //wypisanie numeru znaku i ilosci jego wystapien
  151.             fprintf(plik, "%d %d \n", model[i].indeks_znaku, model[i].ilosc_wystapien);
  152.         }
  153.         //zamkniecie pliku
  154.         fclose(plik);
  155.     }  
  156. }
  157. int model_zrodla_informacji(char *nazwa_pliku, char *nazwa_pliku_model, char *nazwa_pliku_drzewo, char *nazwa_pliku_sort, struct element_zrodla model[])
  158. {
  159.     policz_symbole(nazwa_pliku, nazwa_pliku_model, nazwa_pliku_drzewo, model);
  160.     posortuj_symbole(model, licznik_symboli, nazwa_pliku_sort);
  161.     return 0;
  162. }
  163.  
  164. //Glowna funkcja programu
  165.  
  166. int main(int argc, char *argv[]){
  167.  
  168.     int dlugosc_pliku = 0;  
  169.     char wybor; //zmienna okreslajaca wybór dokonany przez uzytkownika (wpisana wartosc w menu)
  170.     char nazwa_pliku[MAX_PATH]; //zmienna okreslajaca nazwe pliku do kompresji
  171.     char *nazwa_pliku_model; //nazwa pliku dla modelu zródla
  172.     char *nazwa_pliku_sort; //nazwa pliku po sortowani
  173.     char *nazwa_pliku_drzewo; //nazwa pliku z drzewem kodowania
  174.     char rozszerzenie_modelu[] = "model"; //rozszerzenie pliku z modelem
  175.     char rozszerzenie_sort[] = "sort"; //rozszerzenie modelu po sortowaniu
  176.     char rozszerzenie_drzewo[] = "tree"; //rozszerzenie pliku z drzewem kodowania
  177.    
  178.         printf("Teoria Informacji i Kodowania");    
  179.         printf("Program do kodowania i dekodowania Huffmana\n");
  180.         printf("oraz obliczania CRC32\n");
  181.         wybor = 1;
  182.  
  183.         while(wybor == 1 || wybor == 2 || wybor == 3){
  184.             printf("1.Kompresja Huffmana\n");
  185.             printf("Dekompresja Huffmana\n");
  186.             printf("Obliczenie CRC32 dla pliku\n");
  187.             printf("Wyswietlenie tablicy CRC\n");
  188.             printf("Inny znak - wyjscie\n");
  189.  
  190.             //Wczytanie wyboru uzytkownika
  191.             scanf("%d", &wybor);
  192.  
  193.             if (wybor == 1){
  194.  
  195.                 printf("Podaj nazw pliku do kompresji wraz z rozszerzeniem\n");
  196.                 scanf("%s", &nazwa_pliku);
  197.                 while ((nazwa_pliku[dlugosc_pliku] != '\0' && nazwa_pliku[dlugosc_pliku] != kropka))
  198.  
  199.                     dlugosc_pliku++; //zwiekszanie zmiennej pomocniczej
  200.  
  201.                     //okreslenie dlugosci tablic
  202.  
  203.                     nazwa_pliku_model = (char*)malloc(sizeof(char) * (dlugosc_pliku + 1 + (sizeof(rozszerzenie_modelu) / sizeof(rozszerzenie_modelu[0]))));
  204.  
  205.                     nazwa_pliku_sort = (char*)malloc(sizeof(char) * (dlugosc_pliku + 1 + (sizeof(rozszerzenie_sort) / sizeof(rozszerzenie_sort[0]))));
  206.  
  207.                     nazwa_pliku_drzewo = (char*)malloc(sizeof(char) * (dlugosc_pliku + 1 + (sizeof(rozszerzenie_drzewo) / sizeof(rozszerzenie_drzewo[0]))));
  208.  
  209.                      
  210.  
  211.                     stworz_nazwe_pliku(nazwa_pliku, rozszerzenie_modelu, nazwa_pliku_model);
  212.  
  213.                     printf("Nazwa pliku z modelem:              %s\n", nazwa_pliku_model);
  214.  
  215.                     stworz_nazwe_pliku(nazwa_pliku, rozszerzenie_sort, nazwa_pliku_sort);
  216.  
  217.                     printf("Nazwa pliku z posortowanym modelem:       %s\n", nazwa_pliku_sort);
  218.  
  219.                     stworz_nazwe_pliku(nazwa_pliku, rozszerzenie_drzewo, nazwa_pliku_drzewo);
  220.  
  221.                     printf("Nazwa pliku z drzewem kodowania: %s\n", nazwa_pliku_drzewo);
  222.  
  223.                      
  224.  
  225.                     model_zrodla_informacji(nazwa_pliku, nazwa_pliku_model, nazwa_pliku_drzewo, nazwa_pliku_sort, model);
  226.  
  227.                      
  228.  
  229.                     system("PAUSE");
  230.  
  231.             }
  232.  
  233.         }
  234.  
  235. }