Advertisement
Guest User

kurwaniedzialachujstwokurestwo

a guest
Dec 13th, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 83.75 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include <math.h>
  6. #define DL_LINII 1024
  7.  
  8. typedef struct
  9. {
  10.     FILE*    plik;
  11.     char*    nazwa;
  12.     int      typ;
  13.     char**   komentarze;
  14.     int      ilosc_komentarzy;
  15.     int      wysokosc;
  16.     int      szerokosc;
  17.     int      skala;
  18.     int***    piksele_wejsciowe;
  19.     int***    piksele_wyjsciowe;
  20.     int***    piksele_tymczasowe;
  21. }zdjecie;
  22.  
  23.  
  24. /*SPRAWDZANIE POPRAWNOSCI*/
  25. int       czy_plik_istnieje                     (FILE * plik);       // Zwraca 0(tak) -1(nie)
  26. int       czy_plik_jest_niepusty                (FILE * plik);       // Zwraca 0(tak) -1(nie)
  27. int       czy_jest_typ                          (FILE * plik);       // Zwraca [1;6](typ) -1(niepoprawny lub nie ma)
  28. int       czy_sa_wymiary                        (FILE * plik);       // Zwraca 0(tak) -1(niepoprawne) -2(nie ma podanych)
  29. int       czy_jest_podana_skala                 (FILE * plik);       // Zwraca 0(tak) -1(nie)
  30. int       sprawdz_poprawnosc_metadanych_pliku   (FILE * plik);       // Zwraca 0(pli gotowy do dalszych dzialan) -1 nie rozpoczynac z nim pracy
  31.  
  32. int       czy_skala_jest_prawdziwa    (int ** piksele, int skala, int wysokosc, int szerokosc);
  33.  
  34. /*WCZYTYWANIE PLIKU*/
  35. int***    pobierz_piksele            (FILE * plik, int   wysokosc, int   szerokosc, int typ);
  36. void      pobierz_wymiary            (FILE * plik, int * wysokosc, int * szerokosc);
  37. void      pobierz_typ                (FILE * plik, int * typ);
  38. char**    pobierz_komentarze         (FILE * plik, int * ilosc_komentarzy);
  39. void      pobierz_skale              (FILE * plik, int * skala);
  40.  
  41. /*FUNKCJE POMOCNICZE*/
  42. void   zwolnij_tablice_znakow                 (char ** tablica, int ilosc_wierszy);
  43. void   zwolnij_tablice_liczb                  (int  ** tablica, int ilosc_wierszy);
  44. void   zwolnij_pamiec(zdjecie * obraz);
  45. int    czy_jest_cyfra                         (char znak);
  46. int**  normalizuj                             (int ** piksele,  int skala, int wysokosc, int szerokosc);
  47. int    czy_skala_jest_prawdziwa               (int ** piksele,  int skala, int wysokosc, int szerokosc);
  48. int    znajdz_maksimum                        (int ** piksele,             int wysokosc, int szerokosc);
  49. int    znajdz_minimum                         (int ** piksele,             int wysokosc, int szerokosc);
  50.  
  51. /*OPERACJE NA  POJEDYNCZYCH PIKSELACH*/
  52. int**  negatyw                    (int ** piksele, int skala, int wysokosc, int szerokosc);
  53. int**  progowanie                 (int ** piksele, int skala, int wysokosc, int szerokosc);
  54. int**  polprogowanie_czerni       (int ** piksele, int skala, int wysokosc, int szerokosc);
  55. int**  polprogowanie_bieli        (int ** piksele, int skala, int wysokosc, int szerokosc);
  56. int**  korekcja_gamma             (int ** piksele, int skala, int wysokosc, int szerokosc);
  57. int**  zmiana_poziomow            (int ** piksele, int skala, int wysokosc, int szerokosc);
  58. int**  rozciagniecie_histogramu   (int ** piksele, int skala, int wysokosc, int szerokosc);
  59.  
  60. /* OPERACJE LOKALNE(NA KILKU PIKSELACH - NIE MASKI)*/
  61. int** konturowanie               (int ** piksele, int wysokosc, int szerokosc);
  62. int** rozmycie_poziome           (int ** piksele, int wysokosc, int szerokosc);
  63. int** rozmycie_pionowe           (int ** piksele, int wysokosc, int szerokosc);
  64.  
  65. /*OPERACJE Z UZYCIEM MASEK*/
  66. int    ** operacje_z_uzyciem_masek            (int ** piksele, int skala, int wysokosc, int szerokosc, int** maska);
  67. int    ** wybor_maski();
  68. int    ** zwroc_zaalokowana_maske             (int    maska[3][3]);
  69.  
  70. /*FUNCKJE ELEMENTARNE*/
  71. int pobierz_zdjecie (zdjecie * obraz);
  72. void zapisz_plik     (zdjecie * obraz);
  73. /*MENU*/
  74. void   menu_glowne();
  75. void   menu_zdjecia();
  76. int*** menu_pojedynczych (zdjecie * obraz);
  77. int*** menu_lokalnych    (zdjecie * obraz);
  78. int*** menu_masek        (zdjecie * obraz);
  79. int main()
  80. {
  81.     menu_glowne();
  82.  
  83.     return 0;
  84. }
  85. void menu_glowne()
  86. {
  87.         int wybor;
  88.         while(1)
  89.         {
  90.             printf("MENU GLOWNE\n");
  91.             printf("1. Wczytaj zdjecie\n");
  92.             printf("2. Wyjdz\n");
  93.             printf("Twoj wybor:");
  94.             scanf("%d", &wybor);
  95.             printf("|------------------------------------------------------|\n");
  96.             if(wybor == 1)
  97.              {
  98.                 menu_zdjecia();
  99.              }
  100.              else
  101.              {
  102.                 exit(0);
  103.              }
  104.         }
  105. }
  106.  
  107. void menu_zdjecia()
  108. {
  109.  
  110.     zdjecie obraz;
  111.     int czy_wyjsc =  pobierz_zdjecie(&obraz);
  112.  
  113.     if(czy_wyjsc == -1) return;
  114.  
  115.  
  116.     printf("Obslugiwane typy to P1, P2 i P3\n"
  117.            "Program operuje na liczbach calkowitych, wiec niektore operacje na P1 sa nieprzewidywalne\n"
  118.            "Jednak dzialaja, wiec nic nie szkodzi by ich uzywac\n"
  119.            "Na plikach typu P2 wszystkie algorytmy dzialaja poprawnie\n"
  120.            "Na plikach P3 kazdy wybrany algorytm jest uzywany osobno dla wszystkich skladowych\n"
  121.            "Np. negatywa na P3 oznacza zastosowanie go osobno na skladowych R, G i B\n"
  122.            "Wszystkie inne operacje analogicznie.\n");
  123.  
  124.  // wybor operacji jaka chcemy wykonac
  125.     char wybor_operacji[2] = " ";
  126.     printf("Mozliwe do wykonania operacje\n");
  127.     printf("1. Operacje na pojedynczych pikselach\n");
  128.     printf("2. Operacje lokalne\n");
  129.     printf("3. Operacje z uzyciem masek\n");
  130.     printf("Twoj wybor: ");
  131.     scanf("%1s", wybor_operacji);
  132.     printf("|------------------------------------------------------|\n");
  133.  
  134.     if(wybor_operacji[0] == '1')
  135.     {
  136.         obraz.piksele_wyjsciowe = menu_pojedynczych(&obraz);
  137.     }
  138.     else if(wybor_operacji[0] == '2')
  139.     {
  140.         obraz.piksele_wyjsciowe = menu_lokalnych(&obraz);
  141.     }
  142.     else if(wybor_operacji[0] == '3')
  143.     {
  144.         obraz.piksele_wyjsciowe = menu_masek(&obraz);
  145.     }
  146.  
  147.     while(1)
  148.     {
  149.         char menu_dalszej_obrobki_wyjsciowych[2] = " ";
  150.         char menu_dalszej_obrobki_wejsciowych[2] = " ";
  151.         char menu_operacji[2] = " "; // do wyboru opcji ponizej
  152.         printf("|                 Co chcialbys zrobic?                 |\n"
  153.                "|------------------------------------------------------|\n"
  154.                "|                   Piksele wyjsciowe:                 |\n"
  155.                "|1. Zapisac    piksele   wyjsciowe                     |\n"
  156.                "|2. Wyswietlic piksele   wyjsciowe                     |\n"
  157.                "|3. Wykonac na pikselach wyjsciowych dalsze operacje   |\n"
  158.                "|  (usuwa obecne wyjsciowe)                            |\n"
  159.                "|4. Zapisac i wrocic do wyboru pliku                   |\n"
  160.                "|5. Nie zapisywac i wrocic do wyboru pliku             |\n"
  161.                "|------------------------------------------------------|\n"
  162.                "|                   Piksele wejsciowe:                 |\n"
  163.                "|6. Wykonac na nich operacje (usuwa obecne wyjsciowe)  |\n"
  164.                "|7. Wyjsc bez zapisu                                   |\n"
  165.                "|------------------------------------------------------|\n"
  166.                "Twoj wybor: ");
  167.         scanf("%1s", menu_operacji);
  168.         printf("|------------------------------------------------------|\n");
  169.  
  170.         switch(menu_operacji[0])
  171.         {
  172.             case '1':
  173.                     zapisz_plik(&obraz);
  174.             break;
  175.             case '2':
  176.             //TODO
  177.             break;
  178.             case '3':
  179.                     // przygotuj pamiec
  180.                     zwolnij_tablice_liczb(obraz.piksele_wyjsciowe[0], obraz.wysokosc);
  181.                     zwolnij_tablice_liczb(obraz.piksele_wyjsciowe[1], obraz.wysokosc);
  182.                     zwolnij_tablice_liczb(obraz.piksele_wyjsciowe[2], obraz.wysokosc);
  183.                     zwolnij_tablice_liczb(obraz.piksele_wyjsciowe[3], obraz.wysokosc);
  184.                     free(obraz.piksele_wyjsciowe);
  185.                     // wybierz operacje
  186.                     printf("Mozliwe do wykonania operacje\n");
  187.                     printf("1. Operacje na pojedynczych pikselach\n");
  188.                     printf("2. Operacje lokalne\n");
  189.                     printf("3. Operacje z uzyciem masek\n");
  190.                     printf("Twoj wybor: ");
  191.                     scanf("%1s", menu_dalszej_obrobki_wejsciowych);
  192.                     printf("|------------------------------------------------------|\n");
  193.  
  194.                     if(menu_dalszej_obrobki_wejsciowych[0] == '1')
  195.                     {
  196.                         obraz.piksele_wyjsciowe = menu_pojedynczych(&obraz);
  197.                     }
  198.                     else if(wybor_operacji[0] == '2')
  199.                     {
  200.                         obraz.piksele_wyjsciowe = menu_lokalnych(&obraz);
  201.                     }
  202.                     else if(wybor_operacji[0] == '3')
  203.                     {
  204.                         obraz.piksele_wyjsciowe = menu_masek(&obraz);
  205.                     }
  206.             break;        case '4':
  207.                     zapisz_plik(&obraz);
  208.                     zwolnij_pamiec(&obraz);
  209.                     return;
  210.             case '5':
  211.                     zwolnij_pamiec(&obraz);
  212.                     return;
  213.             break;
  214.             case '6':
  215.                     /* przypisz piksele wejsciowe do tymczasowych
  216.                      w celu zmiany wskaznika wejsciowych na wskaznik wyjsciowych
  217.                      potem je odpowiedni przywroci tj
  218.  
  219.                      Poczatek
  220.                      wejsciowe - jakies piksele 1
  221.                      tymczasowe - NULL
  222.                      wyjsciowe - jakies piksele 2
  223.                      Potem
  224.                      wejsciowe - jakies piksele 2
  225.                      tymczasowe - jakies piksele 1
  226.                      wyjsciowe - NULL
  227.                      Koniec
  228.                      wejsciowe - jakies piksele 1
  229.                      tymczasowe - NULL
  230.                      wyjsciowe - jakies piksele 3
  231.                     */
  232.                     obraz.piksele_tymczasowe = obraz.piksele_wejsciowe;
  233.                     obraz.piksele_wejsciowe = obraz.piksele_wyjsciowe;
  234.                     obraz.piksele_wyjsciowe = NULL;
  235.                     // wybierz i wykonaj operacje
  236.                     printf("Mozliwe do wykonania operacje\n");
  237.                     printf("1. Operacje na pojedynczych pikselach\n");
  238.                     printf("2. Operacje lokalne\n");
  239.                     printf("3. Operacje z uzyciem masek\n");
  240.                     printf("Twoj wybor: ");
  241.                     scanf("%1s", menu_dalszej_obrobki_wyjsciowych);
  242.                     printf("|------------------------------------------------------|\n");
  243.  
  244.                     if(menu_dalszej_obrobki_wyjsciowych[0] == '1')
  245.                     {
  246.                         obraz.piksele_wyjsciowe = menu_pojedynczych(&obraz);
  247.                     }
  248.                     else if(wybor_operacji[0] == '2')
  249.                     {
  250.                         obraz.piksele_wyjsciowe = menu_lokalnych(&obraz);
  251.                     }
  252.                     else if(wybor_operacji[0] == '3')
  253.                     {
  254.                         obraz.piksele_wyjsciowe = menu_masek(&obraz);
  255.                     }
  256.                     // po zakonczeniu przywroc piksele wejsciowe z tymczasowych
  257.                     obraz.piksele_wejsciowe = obraz.piksele_tymczasowe;
  258.                     obraz.piksele_tymczasowe = NULL;
  259.  
  260.             break;
  261.             case '7':
  262.                     exit(0);
  263.             break;
  264.         }
  265.     }
  266. }
  267.  
  268. void zapisz_plik(zdjecie * obraz)
  269. {
  270.  
  271.     /*
  272.         Dzialanie:
  273.                     Zapisuje:
  274.                         typ pliku
  275.                         komentarze
  276.                         wymiary
  277.                         skale szarosci
  278.                         piksele wyjsciowe
  279.     */
  280.     char* nazwa = (char*)malloc(sizeof(char) * 100);
  281.  
  282.     printf("Pod jaka nazwa zapisac plik:\n");
  283.     printf("Jesli istnieje plik o takiej samej nazwie to zostanie wymazany i nadpisany\n");
  284.     printf("Nazwa powinna miec lacznie 10 znakow\n");
  285.     scanf("%s", nazwa);
  286.     printf("|------------------------------------------------------|\n");
  287.  
  288.     // otworz plik do zapisu
  289.     FILE* plik = fopen(nazwa, "w+");
  290.  
  291.     // zapisz typ
  292.     printf("Zapisuje typ\n");
  293.     fprintf(plik, "P%d\n", obraz->typ);
  294.  
  295.     // zapisz komentarze jesli istnieja(zawieraja w sobie znak nowej linii to go nie dodajemy)
  296.     if(obraz->ilosc_komentarzy > 0)
  297.     {
  298.         printf("Zapisuje komentarze\n");
  299.         for(int i = 0; i < obraz->ilosc_komentarzy; i++)
  300.         {
  301.             fprintf(plik, "%s", obraz->komentarze[i]);
  302.         }
  303.     }
  304.     // zapisz wymiary
  305.     printf("Zapisuje wymiary\n");
  306.     fprintf(plik, "%d %d\n", obraz->szerokosc, obraz->wysokosc);
  307.  
  308.     // zapisz skale jesli p23
  309.     if(obraz->typ == 2 || obraz->typ == 3)
  310.     {
  311.         printf("Zapisuje skale szarosci\n");
  312.         fprintf(plik, "%d \n", obraz->skala);
  313.     }
  314.     // zapisz piksele P12
  315.     printf("Zapisuje piksele\n");
  316.     if(obraz-> typ == 1 || obraz->typ == 2)
  317.     {
  318.         for(int wys = 0; wys < obraz->wysokosc; wys++)
  319.         {
  320.             for(int szer = 0; szer < obraz->szerokosc; szer++)
  321.             {
  322.                 fprintf(plik,"%d ", obraz->piksele_wyjsciowe[3][wys][szer]);
  323.             }
  324.             fprintf(plik,"\n");
  325.         }
  326.     }
  327.     // zapisz piksele P3
  328.     if(obraz-> typ == 3)
  329.     {
  330.         for(int wys = 0; wys < obraz->wysokosc; wys++)
  331.         {
  332.             for(int szer = 0; szer < obraz->szerokosc; szer++)
  333.             {
  334.                 fprintf(plik,"%d %d %d ",obraz->piksele_wyjsciowe[0][wys][szer],
  335.                                          obraz->piksele_wyjsciowe[1][wys][szer],
  336.                                          obraz->piksele_wyjsciowe[2][wys][szer]);
  337.             }
  338.             fprintf(plik,"\n");
  339.         }
  340.     }
  341.  
  342.     // zamknij plik
  343.     fclose(plik);
  344. }
  345.  
  346. int *** menu_masek(zdjecie * obraz)
  347. {
  348.     int ** maska = wybor_maski(); // wybierz maske
  349.  
  350.     int *** piksele_wyjsciowe = NULL;
  351.     // allokuj tablice kolorow
  352.     piksele_wyjsciowe = (int***) malloc(sizeof(int**) * 4);
  353.     // allokuj wiersze
  354.     for(int i = 0; i < 4 ; i++)
  355.     {
  356.         piksele_wyjsciowe[i] = (int**) malloc(sizeof(int*) * obraz->wysokosc);
  357.     }
  358.     // allokuj kolumny
  359.     for(int i = 0; i < obraz->wysokosc; i++)
  360.     {
  361.         piksele_wyjsciowe[0][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
  362.         piksele_wyjsciowe[1][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
  363.         piksele_wyjsciowe[2][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
  364.         piksele_wyjsciowe[3][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
  365.     }
  366.  
  367.     if(obraz->typ == 1 || obraz->typ == 2)
  368.     {
  369.         piksele_wyjsciowe[3] = operacje_z_uzyciem_masek(obraz->piksele_wejsciowe[3],
  370.                                                      obraz->skala,
  371.                                                      obraz->wysokosc,
  372.                                                      obraz->szerokosc,
  373.                                                      maska);
  374.  
  375.     }
  376.     else if(obraz->typ == 3)
  377.     {
  378.         piksele_wyjsciowe[0] = operacje_z_uzyciem_masek(obraz->piksele_wejsciowe[0],
  379.                                                      obraz->skala,
  380.                                                      obraz->wysokosc,
  381.                                                      obraz->szerokosc,
  382.                                                      maska);
  383.         piksele_wyjsciowe[1] = operacje_z_uzyciem_masek(obraz->piksele_wejsciowe[1],
  384.                                                      obraz->skala,
  385.                                                      obraz->wysokosc,
  386.                                                      obraz->szerokosc,
  387.                                                      maska);
  388.         piksele_wyjsciowe[2] = operacje_z_uzyciem_masek(obraz->piksele_wejsciowe[2],
  389.                                                      obraz->skala,
  390.                                                      obraz->wysokosc,
  391.                                                      obraz->szerokosc,
  392.                                                      maska);
  393.  
  394.     }
  395.     free(maska);
  396.     // normalizuj
  397.     piksele_wyjsciowe[0] = normalizuj(piksele_wyjsciowe[0], obraz->skala, obraz->wysokosc, obraz->szerokosc);
  398.     piksele_wyjsciowe[1] = normalizuj(piksele_wyjsciowe[1], obraz->skala, obraz->wysokosc, obraz->szerokosc);
  399.     piksele_wyjsciowe[2] = normalizuj(piksele_wyjsciowe[2], obraz->skala, obraz->wysokosc, obraz->szerokosc);
  400.     piksele_wyjsciowe[3] = normalizuj(piksele_wyjsciowe[3], obraz->skala, obraz->wysokosc, obraz->szerokosc);
  401.     return piksele_wyjsciowe;
  402. }
  403. int *** menu_lokalnych(zdjecie * obraz)
  404. {
  405.     int *** piksele_wyjsciowe = NULL;
  406.     // allokuj tablice kolorow
  407.     piksele_wyjsciowe = (int***) malloc(sizeof(int**) * 4);
  408.     // allokuj wiersze
  409.     for(int i = 0; i < 4 ; i++)
  410.     {
  411.         piksele_wyjsciowe[i] = (int**) malloc(sizeof(int*) * obraz->wysokosc);
  412.     }
  413.     // allokuj kolumny
  414.     for(int i = 0; i < obraz->wysokosc; i++)
  415.     {
  416.         piksele_wyjsciowe[0][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
  417.         piksele_wyjsciowe[1][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
  418.         piksele_wyjsciowe[2][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
  419.         piksele_wyjsciowe[3][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
  420.     }
  421.  
  422.     // wybrana_operacja[0] operacji
  423.     char wybrana_operacja[2] = " ";
  424.  
  425.     printf("Prosze wybrac operacje, ktora chcialbys wykonac.\n");
  426.     printf("1. Konturowanie\n");
  427.     printf("2. Rozmycie poziome\n");
  428.     printf("3. Rozmycie pionowe\n");
  429.     printf("Twoj wybor to:");
  430.     scanf("%1s", wybrana_operacja);
  431.     printf("|------------------------------------------------------|\n");
  432.  
  433.     if(wybrana_operacja[0] == '1')
  434.     {
  435.         if(obraz->typ == 1 || obraz->typ == 2)
  436.         {
  437.             piksele_wyjsciowe[3] = konturowanie(obraz->piksele_wejsciowe[3], obraz->wysokosc, obraz->szerokosc);
  438.         }
  439.         else if(obraz->typ == 3)
  440.         {
  441.             piksele_wyjsciowe[0] = konturowanie(obraz->piksele_wejsciowe[0], obraz->wysokosc, obraz->szerokosc);
  442.             piksele_wyjsciowe[1] = konturowanie(obraz->piksele_wejsciowe[1], obraz->wysokosc, obraz->szerokosc);
  443.             piksele_wyjsciowe[2] = konturowanie(obraz->piksele_wejsciowe[2], obraz->wysokosc, obraz->szerokosc);
  444.         }
  445.     }
  446.     if(wybrana_operacja[0] == '2')
  447.     {
  448.         if(obraz->typ == 1 || obraz->typ == 2)
  449.         {
  450.             piksele_wyjsciowe[3] = rozmycie_poziome(obraz->piksele_wejsciowe[3], obraz->wysokosc, obraz->szerokosc);
  451.         }
  452.         else if(obraz->typ == 3)
  453.         {
  454.             piksele_wyjsciowe[0] = rozmycie_poziome(obraz->piksele_wejsciowe[0], obraz->wysokosc, obraz->szerokosc);
  455.             piksele_wyjsciowe[1] = rozmycie_poziome(obraz->piksele_wejsciowe[1], obraz->wysokosc, obraz->szerokosc);
  456.             piksele_wyjsciowe[2] = rozmycie_poziome(obraz->piksele_wejsciowe[2], obraz->wysokosc, obraz->szerokosc);
  457.         }
  458.     }
  459.     if(wybrana_operacja[0] == '3')
  460.     {
  461.         if(obraz->typ == 1 || obraz->typ == 2)
  462.         {
  463.             piksele_wyjsciowe[3] = rozmycie_pionowe(obraz->piksele_wejsciowe[3], obraz->wysokosc, obraz->szerokosc);
  464.         }
  465.         else if(obraz->typ == 3)
  466.         {
  467.             piksele_wyjsciowe[0] = rozmycie_pionowe(obraz->piksele_wejsciowe[0], obraz->wysokosc, obraz->szerokosc);
  468.             piksele_wyjsciowe[1] = rozmycie_pionowe(obraz->piksele_wejsciowe[1], obraz->wysokosc, obraz->szerokosc);
  469.             piksele_wyjsciowe[2] = rozmycie_pionowe(obraz->piksele_wejsciowe[2], obraz->wysokosc, obraz->szerokosc);
  470.         }
  471.     }
  472.     // normalizuj
  473.     piksele_wyjsciowe[0] = normalizuj(piksele_wyjsciowe[0], obraz->skala, obraz->wysokosc, obraz->szerokosc);
  474.     piksele_wyjsciowe[1] = normalizuj(piksele_wyjsciowe[1], obraz->skala, obraz->wysokosc, obraz->szerokosc);
  475.     piksele_wyjsciowe[2] = normalizuj(piksele_wyjsciowe[2], obraz->skala, obraz->wysokosc, obraz->szerokosc);
  476.     piksele_wyjsciowe[3] = normalizuj(piksele_wyjsciowe[3], obraz->skala, obraz->wysokosc, obraz->szerokosc);
  477.     return piksele_wyjsciowe;
  478. }
  479.  
  480. int *** menu_pojedynczych(zdjecie * obraz)
  481. {
  482.  
  483.     int *** piksele_wyjsciowe = NULL;
  484.     // allokuj tablice kolorow
  485.     piksele_wyjsciowe = (int***) malloc(sizeof(int**) * 4);
  486.     // allokuj wiersze
  487.     for(int i = 0; i < 4 ; i++)
  488.     {
  489.         piksele_wyjsciowe[i] = (int**) malloc(sizeof(int*) * obraz->wysokosc);
  490.     }
  491.     // allokuj kolumny
  492.     for(int i = 0; i < obraz->wysokosc; i++)
  493.     {
  494.         piksele_wyjsciowe[0][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
  495.         piksele_wyjsciowe[1][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
  496.         piksele_wyjsciowe[2][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
  497.         piksele_wyjsciowe[3][i] = (int*)malloc(sizeof(int) * obraz->szerokosc);
  498.     }
  499.     // wybor operacji
  500.     char wybrana_operacja[2] = " ";
  501.     printf("Prosze wybrac operacje, ktora chcialbys wykonac.\n");
  502.     printf("1. Negatyw\n");
  503.     printf("2. Progowanie\n");
  504.     printf("3. Polprogowanie czerni\n");
  505.     printf("4. Polprogowanie bieli\n");
  506.     printf("5. Korekcja gamma\n");
  507.     printf("6. Zmiana poziomow\n");
  508.     printf("7. Rozciagniecie histogramu\n");
  509.     printf("Twoj wybor to:");
  510.     scanf("%1s", wybrana_operacja);
  511.     printf("|------------------------------------------------------|\n");
  512.  
  513.         // negatyw
  514.         if(wybrana_operacja[0] == '1')
  515.         {
  516.             if(obraz->typ == 1 || obraz->typ == 2)
  517.             {
  518.                 piksele_wyjsciowe[3] = negatyw(obraz->piksele_wejsciowe[3],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  519.             }
  520.             else if(obraz->typ == 3)
  521.             {
  522.                 piksele_wyjsciowe[0] = negatyw(obraz->piksele_wejsciowe[0],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  523.                 piksele_wyjsciowe[1] = negatyw(obraz->piksele_wejsciowe[1],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  524.                 piksele_wyjsciowe[2] = negatyw(obraz->piksele_wejsciowe[2],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  525.             }
  526.         }
  527.         // progowanie
  528.         else if(wybrana_operacja[0] == '2')
  529.         {
  530.             if(obraz->typ == 1 || obraz->typ == 2)
  531.             {
  532.                 piksele_wyjsciowe[3] = progowanie(obraz->piksele_wejsciowe[3],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  533.             }
  534.             else if(obraz->typ == 3)
  535.             {
  536.                 piksele_wyjsciowe[0] = progowanie(obraz->piksele_wejsciowe[0],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  537.                 piksele_wyjsciowe[1] = progowanie(obraz->piksele_wejsciowe[1],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  538.                 piksele_wyjsciowe[2] = progowanie(obraz->piksele_wejsciowe[2],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  539.             }
  540.         }
  541.         // polprogowanie czerni
  542.         else if(wybrana_operacja[0] == '3')
  543.         {
  544.             if(obraz->typ == 1 || obraz->typ == 2)
  545.             {
  546.                 piksele_wyjsciowe[3] = polprogowanie_czerni(obraz->piksele_wejsciowe[3],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  547.             }
  548.             else if(obraz->typ == 3)
  549.             {
  550.                 piksele_wyjsciowe[0] = progowanie(obraz->piksele_wejsciowe[0], obraz->skala, obraz->wysokosc, obraz->szerokosc);
  551.                 piksele_wyjsciowe[1] = progowanie(obraz->piksele_wejsciowe[1], obraz->skala, obraz->wysokosc, obraz->szerokosc);
  552.                 piksele_wyjsciowe[2] = progowanie(obraz->piksele_wejsciowe[2], obraz->skala, obraz->wysokosc, obraz->szerokosc);
  553.             }
  554.         }
  555.         // polprogowanie bieli
  556.         else if(wybrana_operacja[0] == '4')
  557.         {
  558.             if(obraz->typ == 1 || obraz->typ == 2)
  559.             {
  560.                 piksele_wyjsciowe[3] = polprogowanie_bieli(obraz->piksele_wejsciowe[3],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  561.             }
  562.             else if(obraz->typ == 3)
  563.             {
  564.                 piksele_wyjsciowe[0] = polprogowanie_bieli(obraz->piksele_wejsciowe[0],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  565.                 piksele_wyjsciowe[1] = polprogowanie_bieli(obraz->piksele_wejsciowe[1],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  566.                 piksele_wyjsciowe[2] = polprogowanie_bieli(obraz->piksele_wejsciowe[2],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  567.             }
  568.         }
  569.         // korekcja gamma
  570.         else if(wybrana_operacja[0] == '5')
  571.         {
  572.             if(obraz->typ == 1 || obraz->typ == 2)
  573.             {
  574.                 piksele_wyjsciowe[3] = korekcja_gamma(obraz->piksele_wejsciowe[3],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  575.             }
  576.             else if(obraz->typ == 3)
  577.             {
  578.                 piksele_wyjsciowe[0] = korekcja_gamma(obraz->piksele_wejsciowe[0],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  579.                 piksele_wyjsciowe[1] = korekcja_gamma(obraz->piksele_wejsciowe[1],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  580.                 piksele_wyjsciowe[2] = korekcja_gamma(obraz->piksele_wejsciowe[2],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  581.             }
  582.         }
  583.         else if(wybrana_operacja[0] == '6')
  584.         {
  585.             if(obraz->typ == 1 || obraz->typ == 2)
  586.             {
  587.                 piksele_wyjsciowe[3] = zmiana_poziomow(obraz->piksele_wejsciowe[3],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  588.             }
  589.             else if(obraz->typ == 3)
  590.             {
  591.                 piksele_wyjsciowe[0] = zmiana_poziomow(obraz->piksele_wejsciowe[0],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  592.                 piksele_wyjsciowe[1] = zmiana_poziomow(obraz->piksele_wejsciowe[1],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  593.                 piksele_wyjsciowe[2] = zmiana_poziomow(obraz->piksele_wejsciowe[2],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  594.             }
  595.         }
  596.         else if(wybrana_operacja[0] == '7')
  597.         {
  598.             if(obraz->typ == 1 || obraz->typ == 2)
  599.             {
  600.                 piksele_wyjsciowe[3] = rozciagniecie_histogramu(obraz->piksele_wejsciowe[3],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  601.             }
  602.             else if(obraz->typ == 3)
  603.             {
  604.                 piksele_wyjsciowe[0] = rozciagniecie_histogramu(obraz->piksele_wejsciowe[0],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  605.                 piksele_wyjsciowe[1] = rozciagniecie_histogramu(obraz->piksele_wejsciowe[1],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  606.                 piksele_wyjsciowe[2] = rozciagniecie_histogramu(obraz->piksele_wejsciowe[2],obraz->skala, obraz->wysokosc, obraz->szerokosc);
  607.             }
  608.         }
  609.  
  610.     // normalizuj
  611.     else if(obraz->typ == 3)
  612.     {
  613.         piksele_wyjsciowe[0] = normalizuj(piksele_wyjsciowe[0], obraz->skala, obraz->wysokosc, obraz->szerokosc);
  614.         piksele_wyjsciowe[1] = normalizuj(piksele_wyjsciowe[1], obraz->skala, obraz->wysokosc, obraz->szerokosc);
  615.         piksele_wyjsciowe[2] = normalizuj(piksele_wyjsciowe[2], obraz->skala, obraz->wysokosc, obraz->szerokosc);
  616.     }
  617.     if(obraz->typ == 1 || obraz->typ == 2)
  618.     {
  619.         piksele_wyjsciowe[3] = normalizuj(piksele_wyjsciowe[3], obraz->skala, obraz->wysokosc, obraz->szerokosc);
  620.     }
  621.     return piksele_wyjsciowe;
  622. }
  623. int pobierz_zdjecie(zdjecie * obraz)
  624. {
  625.     // Wybor zdjecie przez uzytkownika
  626.     obraz->nazwa = (char*)malloc(sizeof(char) * 10);
  627.     printf("Prosze podac nazwe zdjecie, ktore ma byc wczytane(maks 100 znakow):");
  628.     scanf("%s", obraz->nazwa);
  629.     printf("|------------------------------------------------------|\n");
  630.     obraz->piksele_tymczasowe = NULL;
  631.   // WSTEPNA KONTROLA POPRAWNOSCI
  632.         //--------------------------------------------------------------------------------------------------------------------------------
  633.         /* Otworz plik i sprawdz jego poprawnosc tj.
  634.             1. Czy istnieje?                              (Czy da sie go otworzyc?)
  635.             2. Czy jest niepusty?                         (Czy 1 znak to EOF?)
  636.             3. Czy ma podany typ?                         (czy 2 znak pliku to  1,2,3,4,5,6
  637.             4. Czy ma podane OBA wymiary?                 (Czy sa one minimalnie 3x3? i Czy oba istnieja?)
  638.             5. Czy ma podana skale szarosc/ilosc odcieni? (Czy skala istnieje? i Czy jest wieksza niz 0?)
  639.  
  640.             Jesli nie to wypisuje co sie nie zgadza i wraca do menu glownego
  641.             Jesli tak to kontynuuje
  642.  
  643.  
  644.         */
  645.     obraz->plik = fopen(obraz->nazwa, "r");
  646.     int poprawnosc = sprawdz_poprawnosc_metadanych_pliku(obraz->plik);
  647.  
  648.     if( poprawnosc != 0) // w jakis sposob niepoprawny
  649.     {
  650.         // gdy nie istnieje to funkcja zwroci -100
  651.         // warunek istnienia jest o tyle wazniejszy od innych,
  652.         // ze zamkniecie pliku wtedy powoduje blad
  653.         if(poprawnosc != -100) fclose(obraz->plik);
  654.  
  655.         printf("Obraz nie przeszedl pomyslnie kontroli poprawnosci \nWychodze do menu glownego\n");
  656.         printf("|------------------------------------------------------|\n");
  657.         return -1;
  658.     }
  659.  
  660.     // pobierz typ zdjecia (na pewno jest wsrod 123456 gdyz w kontroli poprawnosci o to zadbalismy)
  661.     pobierz_typ(obraz->plik, &obraz->typ);
  662.  
  663.     // nie czytaj binarnych
  664.     switch(obraz->typ)
  665.     {
  666.         // obslugiwane formaty P123 nie rob nic
  667.         case 1:
  668.              break;
  669.         case 2:
  670.              break;
  671.         case 3:
  672.              break;
  673.         // nieobslugiwane formaty
  674.         case 4:
  675.               printf("Program nie obsluguje formatu P%d \nWychodze do menu glownego\n", obraz->typ);
  676.               printf("|------------------------------------------------------|\n");
  677.               free(obraz->nazwa);
  678.               fclose(obraz->plik);
  679.               return -1;
  680.              break;
  681.         case 5:
  682.               printf("Program nie obsluguje formatu P%d \nWychodze do menu glownego\n", obraz->typ);
  683.               printf("|------------------------------------------------------|\n");
  684.               free(obraz->nazwa);
  685.               fclose(obraz->plik);
  686.               return -1;
  687.              break;
  688.         case 6:
  689.               printf("Program nie obsluguje formatu P%d \nWychodze do menu glownego\n", obraz->typ);
  690.               printf("|------------------------------------------------------|\n");
  691.               free(obraz->nazwa);
  692.               fclose(obraz->plik);
  693.               return -1;
  694.              break;
  695.  
  696.  
  697.     }
  698.     // pobierz komentarze i zapisz ich ilosc
  699.     // jesli brak to zwroc null i ustal ich ilosc na 0
  700.     obraz->komentarze = pobierz_komentarze(obraz->plik, &obraz->ilosc_komentarzy);
  701.     // pobierz wymiary. Wiemy, ze na pewno istnieja, sa dodatnie i wieksze nic 3x3
  702.     pobierz_wymiary(obraz->plik, &obraz->wysokosc, &obraz->szerokosc);
  703.     // Pobierz skale szarosci badz odcieni o ile ma to sens P23
  704.     if(obraz->typ == 2 || obraz->typ == 3)
  705.     {
  706.         pobierz_skale(obraz->plik, &obraz->skala);
  707.     }
  708.     // pobierz piksele w tablicy 3d [4][wysokosc][szerokosc]
  709.     obraz->piksele_wejsciowe =  pobierz_piksele(obraz->plik, obraz->wysokosc, obraz->szerokosc, obraz->typ);
  710.  
  711.     /*
  712.      W tym momencie wiemy, że istniejacy, niepusty plik zawiera poprawne metadane
  713.      tj. wiemy:
  714.  
  715.         1. Plik ma podany dobry typ (P1/P2)
  716.         2. Plik ma podane prawidlowe wymiary(min 3x3)
  717.         3. Plik ma podana dobra skale szarosci/ilosc/odcieni(min 2 {0,1} obraz czarno bialy)
  718.  
  719.      Po wczytaniu pikseli nalezy jeszcze sprawdzic:
  720.         1. Czy podana skala szarosci jest rowna rzeczywistej?
  721.             1.1 Znajduje realne minimum  wartosci piksela (RMin)
  722.             1.2 znajduje realne maksimum wartosci piksela (Rmax)
  723.             1.3 Porownuje realne minimum i maksumum z zadeklarowanymi przez plik wartosciami ZMin, ZMax
  724.                 Czy ZMin <= {RMin, RMax} <= RMax
  725.                 PRZYKLAD:
  726.                             ZLE
  727.                    Zdjecie1{RMin; RMax} = {-1;  256}
  728.                    Zdjecie1{ZMin; ZMax} = { 0;  255}
  729.                    Zdjecie1 ma niepoprawne piksele
  730.                             DOBRE
  731.                    Zdjecie2{RMin; RMax} = {0; 255}
  732.                    Zdjecie2{ZMin; ZMax} = {RMin: RMin in [0;255]; RMax in [0;255]}
  733.                    Zdjecie2 ma poprawne piksele
  734.  
  735.         2. Czy podana ilosc pikseli jest rowna rzeczywistej
  736.             2.1 Przy pobieraniu pikseli zapisywac ile ich wystapilo przed EOF
  737.             2.2 Sprawdza czy wysokosc*szerokosc == ilosc_pikseli
  738.                 Jesli nie to wypisuje co sie nie zgadza, zamyka plik i wraca do menu glownego
  739.                 Jesli tak to kontynuuje
  740.         */
  741.  
  742.         // czy skala szarosci zgadza sie z rzeczywista
  743.         if(obraz->typ == 2)
  744.         {
  745.             // sprawdz szarosci
  746.             int czy_skala_sie_zgadza =czy_skala_jest_prawdziwa(obraz->piksele_wejsciowe[3],
  747.                                                                    obraz->skala,
  748.                                                                    obraz->wysokosc,
  749.                                                                    obraz-> szerokosc);
  750.             if(czy_skala_sie_zgadza == -1)
  751.             {
  752.                     printf("Zadeklarowana skala ilosci odcieni szerosci w pliku "
  753.                            "nie zgadza sie z rzeczywista iloscia.\n");
  754.                     printf("Wracam do menu glownego \n\n");
  755.                     printf("|------------------------------------------------------|\n");
  756.  
  757.                     return -1;
  758.             }
  759.         }
  760.         else if(obraz->typ == 3)
  761.         {
  762.             // sprawdz czerwony
  763.             int red   = czy_skala_jest_prawdziwa(obraz->piksele_wejsciowe[0],
  764.                                                  obraz->skala,
  765.                                                  obraz->wysokosc,
  766.                                                  obraz->szerokosc);
  767.             // sprawdz szarosci
  768.             int green = czy_skala_jest_prawdziwa(obraz->piksele_wejsciowe[1],
  769.                                                  obraz->skala,
  770.                                                  obraz->wysokosc,
  771.                                                  obraz->szerokosc);
  772.             // sprawdz szarosci
  773.             int blue  = czy_skala_jest_prawdziwa(obraz->piksele_wejsciowe[2],
  774.                                                  obraz->skala,
  775.                                                  obraz->wysokosc,
  776.                                                  obraz->szerokosc);
  777.  
  778.             if(red + green + blue < 0)
  779.             {
  780.                     printf("Zadeklarowana skala ilosci odcieni w pliku "
  781.                            "nie zgadza sie z rzeczywista iloscia.\n");
  782.                     printf("Wracam do menu glownego \n\n");
  783.                     printf("|------------------------------------------------------|\n");
  784.  
  785.                     return -1;
  786.             }
  787.         }
  788.  
  789.  
  790. }
  791.  
  792. void zwolnij_pamiec(zdjecie * obraz)
  793. {
  794.     // zwolnij nazwe
  795.     free(obraz->nazwa);
  796.     // zwolnij komentarze
  797.     if(obraz->ilosc_komentarzy != 0)
  798.     {
  799.         zwolnij_tablice_znakow(obraz->komentarze, obraz->ilosc_komentarzy);
  800.     }
  801.     // zwolnij piksele wejsciowe jesli istnieja
  802.     if (obraz->piksele_wejsciowe != NULL)
  803.     {
  804.         if(obraz->typ == 3)
  805.         {
  806.             zwolnij_tablice_liczb(obraz->piksele_wejsciowe[0], obraz->wysokosc);
  807.             zwolnij_tablice_liczb(obraz->piksele_wejsciowe[1], obraz->wysokosc);
  808.             zwolnij_tablice_liczb(obraz->piksele_wejsciowe[2], obraz->wysokosc);
  809.         }
  810.         else if(obraz->typ == 1 || obraz->typ == 2)
  811.         {
  812.             zwolnij_tablice_liczb(obraz->piksele_wejsciowe[3], obraz->wysokosc);
  813.         }
  814.         free(obraz->piksele_wejsciowe);
  815.     }
  816.     // zwolni piksele wyjsciowe
  817.     if(obraz->piksele_wyjsciowe != NULL)
  818.     {
  819.         if(obraz->typ == 3)
  820.         {
  821.             zwolnij_tablice_liczb(obraz->piksele_wyjsciowe[0], obraz->wysokosc);
  822.             zwolnij_tablice_liczb(obraz->piksele_wyjsciowe[1], obraz->wysokosc);
  823.             zwolnij_tablice_liczb(obraz->piksele_wyjsciowe[2], obraz->wysokosc);
  824.         }
  825.         else if(obraz->typ == 1 || obraz->typ == 2)
  826.         {
  827.             zwolnij_tablice_liczb(obraz->piksele_wyjsciowe[3], obraz->wysokosc);
  828.         }
  829.         free(obraz->piksele_wyjsciowe);
  830.     }
  831.  
  832.     // zwolnij piksele tymczasowe
  833.     if(obraz->piksele_tymczasowe != NULL)
  834.     {
  835.         if(obraz->typ == 3)
  836.         {
  837.             zwolnij_tablice_liczb(obraz->piksele_tymczasowe[0], obraz->wysokosc);
  838.             zwolnij_tablice_liczb(obraz->piksele_tymczasowe[1], obraz->wysokosc);
  839.             zwolnij_tablice_liczb(obraz->piksele_tymczasowe[2], obraz->wysokosc);
  840.         }
  841.         else if (obraz->typ == 1 || obraz->typ == 2)
  842.         {
  843.             zwolnij_tablice_liczb(obraz->piksele_tymczasowe[3], obraz->wysokosc);
  844.         }
  845.         free(obraz->piksele_tymczasowe);
  846.     }
  847.  
  848.     // zamknij uchwyt pliku
  849.  
  850.     fclose(obraz->plik);
  851.  
  852.  
  853. }
  854. int czy_plik_istnieje( FILE * plik)
  855. {
  856.  
  857.     /*
  858.         Argumenty: uchwyt do pliku
  859.         Zwraca:    0 plik     istnieje
  860.                   -1 plik nie istnieje
  861.     */
  862.  
  863.     // czy plik NIE istnieje?
  864.     if(plik == NULL)    return -1;
  865.     else                return  0;
  866.  
  867.  
  868. }
  869.  
  870. int czy_plik_jest_niepusty(FILE * plik)
  871. {
  872.  
  873.     /*
  874.         Argumenty: uchwyt do pliku
  875.         Zwraca:    0 plik nie jest pusty
  876.                   -1 plik jest pusty
  877.     */
  878.     // przewin na poczatek na wszelki wypadek
  879.     rewind(plik);
  880.     // pobierz 1 znak i sprawdz czy nie jest znakiem konca pliku
  881.     char pierwszy_znak = fgetc(plik);
  882.     if(pierwszy_znak == EOF)        return -1;
  883.     else                            return  0;
  884.  
  885. }
  886. int czy_sa_wymiary(FILE * plik)
  887. {
  888.     /*
  889.         Argumenty: wskaznik na plik
  890.         Zwraca:    0 sa podane odpowiednie wymiary
  891.                   -1 nie ma podanych odpowiednich wymiarow
  892.  
  893.         Dzialanie:
  894.  
  895.                 1. Pomija typ pliku
  896.                 2. Pomija komentarze
  897.                 3. Sprawdza czy istnieja dodatnie wymiary
  898.  
  899.                 Funkcja ta opiera sie na formacie plikow.
  900.                 PIERWSZA LINIA w ktorej PIERWSZY ZNAK jest CYFRA to linia z wymiarami tj.
  901.                 PRZYKLAD:
  902.                 Px
  903.                 # jakies kometarze
  904.                 100 100 <- pierwsza linia z cyfra jako 1 znak to wymiary
  905.                 Gdy dojdziemy do tej linii przerywamy przewijanie pliku
  906.                 oraz wczytujemy dane z bufora i sprawdzany nastepujace warunki:
  907.  
  908.                 1. Czy wymiar oznaczajacy szerokosc istnieje? (czy fscanf zwroci 2)
  909.                 2. Czy wymiar oznaczajacy wysokosc  istnieje? (czy fscanf zwroci 2)
  910.                 3. Czy OBA wymiary sa wieksze od 3x3?
  911.  
  912.                 Warunek 3 jest niekonieczny, gdyz niektore operacje mozna wykonac na pojedynczych
  913.                 pikselach np. negatyw.
  914.                 Jednakże obsluga takiego typu plikow znaczaco zwieksza ilosc wymaganej kontroli bledow
  915.                 oraz ma znikomy sens i dlatego nie nie sa one obslugiwane.
  916.     */
  917.  
  918.  
  919.     rewind(plik); // na wszelki wypadek przewin na poczatek
  920.     char bufor[DL_LINII];   // bufor pomocniczy
  921.     char * czy_koniec; // zmienna pomocnicza
  922.  
  923.     // pobierz 1 linie
  924.     czy_koniec = fgets(bufor, DL_LINII, plik);
  925.  
  926.     do
  927.     {
  928.         // Pomin typ pliku
  929.         if(bufor[0] == 'P')
  930.         {
  931.             // pobierz nastepna linie
  932.             czy_koniec = fgets(bufor, DL_LINII, plik);
  933.             continue;
  934.         }
  935.         // pomin komentarze
  936.         else if(bufor[0] == '#')
  937.         {
  938.             // pobierz nastepna linie
  939.             czy_koniec = fgets(bufor, DL_LINII, plik);
  940.             continue;
  941.         }
  942.         // pomin linie zaczynajace sie od pustych znakow
  943.         else if(isspace(bufor[0]))
  944.         {
  945.             // pobierz nastepna linie
  946.             czy_koniec = fgets(bufor, DL_LINII, plik);
  947.             continue;
  948.         }
  949.         /*
  950.             Gdy przy czytaniu pliku po raz pierwszy pojawi sie linie, ktora nie zaczyna sie od
  951.             P, #, \n
  952.             To jest to linia z wymiarami. Nastapi to przy 1 wywolaniu else
  953.         */
  954.         else
  955.         {
  956.             // wypelnij wymiaru ujemnymi liczbami
  957.             int wymx = -1, wymy = -1;
  958.             // wczytaj wymiary z bufora
  959.             int ilosc_wymiarow = sscanf(bufor, "%d %d", &wymx, &wymy);
  960.  
  961.             // Jesli wymiary istnieja i sa wieksze/rowne niz 3x3
  962.             // jesli nie udalo sie wczytac chociaz jednej piksele to 2 warunki beda bledne
  963.             // gdyz wartosc pewnego wymiaru pozostanie rowna -1 i zmienna pomocnicza nie bedzie rowna 2
  964.             if( wymx >= 3 && wymy >= 3 && ilosc_wymiarow == 2)
  965.             {
  966.                 return 0;
  967.             }
  968.             else
  969.             {
  970.                 return -1;
  971.             }
  972.         }
  973.  
  974.     }
  975.     while(czy_koniec != NULL);
  976.     return -1;
  977.  
  978. }
  979.  
  980. int czy_jest_podana_skala(FILE * plik)
  981. {
  982.     /*
  983.         Argumenty: wskaznik na plik
  984.         Zwraca:    0 Jest podana poprawna skala
  985.                   -1 nie ma podanej skali
  986.                   -2 skala jest niepoprawna np -10
  987.         Dzialanie:
  988.                 1. Pomija typ pliku
  989.                 2. Pomija komentarze
  990.                 3. Pomija wymiary
  991.                 4. Sprawdza czy jest podana dodatnie(minimum 1) skala szarosci
  992.  
  993.     */
  994.     // zapobiegawczo przewin na poczatek
  995.     rewind(plik);
  996.  
  997.     char bufor[DL_LINII];
  998.     char * czy_koniec; //  zmienna pomocnicza
  999.  
  1000.     // pobierz 1 linie
  1001.     czy_koniec = fgets(bufor, DL_LINII, plik);
  1002.  
  1003.     do
  1004.     {
  1005.         // Pomin typ pliku
  1006.         if(bufor[0] == 'P')
  1007.         {
  1008.             // pobierz nastepna linie
  1009.             czy_koniec = fgets(bufor, DL_LINII, plik);
  1010.             continue;
  1011.         }
  1012.         // pomin komentarze
  1013.         else if(bufor[0] == '#')
  1014.         {
  1015.             // pobierz nastepna linie
  1016.             czy_koniec = fgets(bufor, DL_LINII, plik);
  1017.             continue;
  1018.         }
  1019.         // pomin puste linie
  1020.         else if(isspace(bufor[0]))
  1021.         {
  1022.             // pobierz nastepna linie
  1023.             czy_koniec = fgets(bufor, DL_LINII, plik);
  1024.             continue;
  1025.         }
  1026.         else
  1027.         {
  1028.             // Pierwsza linia po komentarzach to wymiary -> Pomijamy;
  1029.             // pobierz nastepna linie -> Teoretycznie tam powinny byc odcienie
  1030.  
  1031.  
  1032.             if(fgets(bufor, DL_LINII, plik) != NULL)
  1033.             {
  1034.                 // Czy ilosc odcieni istnieje i jest wieksza od 1
  1035.                 int skala;
  1036.                 sscanf(bufor, "%d", &skala);
  1037.                 if(skala > 1)
  1038.                 {
  1039.                     return 0;
  1040.                 }
  1041.                 // jesli jest mniejsza/rowna 1 oznacza to, ze wartosc jest niepoprawna
  1042.                 else
  1043.                 {
  1044.                     return -1;
  1045.                 }
  1046.             }
  1047.             // jesli nie ma w ogole ilosci odcieni
  1048.             else
  1049.             {
  1050.                 return -2;
  1051.             }
  1052.         }
  1053.  
  1054.     }
  1055.     while(czy_koniec != NULL);
  1056.     return -1;
  1057. }
  1058.  
  1059. int czy_jest_typ(FILE * plik)
  1060. {
  1061.     /*
  1062.         Sprawdza czy plik ma poprawny typ
  1063.         Zwracana wartosc mozna porownac z zerem przy sprawdzaniu poprawnosci
  1064.         Zwraca :
  1065.                  [1;6] jesli typ jest     poprawny(typ obrazu)
  1066.                   -1   jesli typ jest nie poprawny
  1067.     */
  1068.  
  1069.  
  1070.     // pojdz na poczatek
  1071.     rewind(plik);
  1072.     // pobierz 2 pierwsze znaki
  1073.     char typ[DL_LINII];
  1074.     char * czy_koniec = fgets(typ, DL_LINII, plik);
  1075.  
  1076.     // Zwroc typ obrazu
  1077.     if(typ[0] == 'P' && czy_koniec != NULL)
  1078.     {
  1079.         // zaleznie od typu zwroc jego wartosc
  1080.         switch(typ[1])
  1081.         {
  1082.             case '1':
  1083.                     return 1;
  1084.                     break;
  1085.             case '2':
  1086.                     return 2;
  1087.                     break;
  1088.             case '3':
  1089.                     return 3;
  1090.                     break;
  1091.             case '4':
  1092.                     return 4;
  1093.                     break;
  1094.             case '5':
  1095.                     return 5;
  1096.                     break;
  1097.             case '6':
  1098.                     return 6;
  1099.                     break;
  1100.             // gdyby byla inna cyfra np P9 to uznaj to za niepoprawny typ
  1101.             default:
  1102.                     return -1;
  1103.                     break;
  1104.         }
  1105.     }
  1106.     else if (typ[0] != 'P' || czy_koniec == NULL)
  1107.     {
  1108.         return -1;
  1109.     }
  1110.  
  1111.     return -1;
  1112. }
  1113.  
  1114. int sprawdz_poprawnosc_metadanych_pliku(FILE * plik)
  1115. {
  1116.     /*
  1117.         Opis:
  1118.             Wczesniejsze kontrola metadanych pliku ma na celu(w takiej kolejnosci) sprawdzic:
  1119.                 1. Czy plik istnieje?
  1120.                     TAK -> poinformuj i kontynuuj
  1121.                     NIE -> poinformuj i zwroc -2 i wyjdz z funkcji
  1122.                 2. Czy plik jest NIEpusty?
  1123.                     TAK -> poinformuj i kontynuuj
  1124.                     NIE -> poinformuj i zwroc -1 i wyjdz z funkcji
  1125.                 3. Czy plik ma podany poprawny typ?
  1126.                     TAK -> poinformuj, odnotuj i kontynuuj
  1127.                     NIE -> poinformuj, odnotuj i kontynuuj
  1128.                 4. Czy plik ma podane wymiary?
  1129.                     TAK -> poinformuj, odnotuj i kontynuuj
  1130.                     NIE -> poinformuj, odnotuj i kontynuuj
  1131.                 5. Jesli plik jest typu P2 lub P3 to:
  1132.                     5.1 Czy ma podana  POPRAWNA skale2?
  1133.                         TAK            -> poinformuj, odnotuj i kontynuuj
  1134.                         NIE MA SKALI   -> poinformuj, odnotuj i kontynuuj
  1135.                         MA NIEPOPRAWNA -> poinformuj, odnotuj i kontynuuj
  1136.  
  1137.             Wykonujac te operacje jeszcze przed zabraniem sie za prace z danymi pliku,
  1138.             sprawdzic czy metadane pliku sa poprawne co wyeliminuje koniecznosc kontroli
  1139.             w trakcie dzialania programu czy np wymiary sa dodatnie albo skala jest poprawna.
  1140.         Dzialanie:
  1141.                     1. Jesli plik nie istnieje (zwroc -2) lub jest pusty(zwroc -1) nie ma sensu sprawdzac
  1142.                        dalszych warunkow (2.). Poinformuj uzytkowanika co jest nie tak
  1143.                     2. Jesli plik ma niepoprawne lub nie ma: typu(P123), wymiarow(P123), skali(P23),
  1144.                        poinformuj uzytkownika o tym fakcie.
  1145.  
  1146.             Kazda mozliwa(prawie, ale reszty sie nie da tutaj sprawdzic w prosty sposob) niepoprawnosc
  1147.             zostanie odnotowana tj.
  1148.                 Jesli, ktoras wymagana wartosc nie jest prawidlowa badz nie istnieje to zmienna
  1149.                        przechowujaca wartosc logiczna przyjmie -1
  1150.                 Jesli, ktoras wymagana wartosc jest prawidowa to zmienna przechowujaca wartosc logiczna
  1151.                        przyjmie 0
  1152.  
  1153.             Nastepnie sumujemy wszystkie te zmienne logiczne(oprocz czy istnieje i czy jest niepusty),
  1154.             w zmiennej, ktorej wartosc na poczatku ustawiona na 0.
  1155.             Jesli po zsumowaniu suma nadal jest rowna 0 to oznacza to, ze zadna nieprawidlowosc wystapila.
  1156.             Jesli po zsumowaniu suma jest mniejsza od 0 to funkcja zwraca -1 co oznacza, ze plik nie powinien
  1157.             zostac wczytany.
  1158.  
  1159.         Zwraca:
  1160.                 0 plik jest poprawny i mozna go wczytac
  1161.                -1 plik nie jest poprawny i odradza sie jego wczytywanie
  1162.     */
  1163.  
  1164.     // 1. Czy w ogole istnieje taki plik?
  1165.     printf("Sprawdzam poprawnosc pliku: \n");
  1166.     int czy_istnieje = czy_plik_istnieje(plik);
  1167.     if(czy_istnieje == -1)
  1168.     {
  1169.         printf("Plik o podanej nazwie nie istnieje\n");
  1170.         return -100;
  1171.     }
  1172.     else
  1173.     {
  1174.         printf("Plik o podanej nazwie istnieje\t\t 1 z 5\n");
  1175.     }
  1176.  
  1177.     // 2. Czy niepusty? Czy ma chociaz jeden znak?
  1178.     int czy_niepusty = czy_plik_jest_niepusty(plik);
  1179.     if(czy_niepusty == -1)
  1180.     {
  1181.         printf("Plik o podanej nazwie jest pusty\n");
  1182.         return -1;
  1183.     }
  1184.     else
  1185.     {
  1186.         printf("Plik o podanej nazwie nie jest pusty\t 2 z 5 \n");
  1187.     }
  1188.  
  1189.     // 3. Czy jest podany typ?
  1190.     int jaki_jest_typ = czy_jest_typ(plik); // zwraca typ lub -1
  1191.     if(jaki_jest_typ == 1 || jaki_jest_typ == 2 || jaki_jest_typ == 3)
  1192.     {
  1193.         printf("Plik ma poprawnie podany typ P%d\t \t 3 z 5 \n", jaki_jest_typ);
  1194.     }
  1195.     else if(jaki_jest_typ == -1)
  1196.     {
  1197.         printf("Plik nie ma poprawnie podanego typu badz typ nie istnieje");
  1198.     }
  1199.     // 4. czy istnieja DWA wymiary WIEKSZE od 3x3?
  1200.     int czy_podano_wymiary  = czy_sa_wymiary(plik);
  1201.     if(czy_podano_wymiary == 0)
  1202.     {
  1203.         printf("Plik ma poprawne wymiary(min 3x3) \t 4 z 5\n");
  1204.     }
  1205.     else if(czy_podano_wymiary == -1)
  1206.     {
  1207.         printf("Plik nie ma poprawnych wymiarow badz nie sa one podane\n");
  1208.     }
  1209.  
  1210.  
  1211.     // czy jest podana skala(gdy typ to P2 lub P3)
  1212.     // korzystamy ze zmiennej z wczesniejszego podpunktu.
  1213.     // Gdyby sie okazalo, ze
  1214.     int czy_jest_skala;
  1215.     if(jaki_jest_typ == 2 || jaki_jest_typ == 3)
  1216.     {
  1217.         czy_jest_skala = czy_jest_podana_skala(plik);
  1218.         // gdy jest poprawna
  1219.         if(czy_jest_skala == 0)
  1220.         {
  1221.             printf("Plik na poprawna skale\t\t\t 5 z 5 \n");
  1222.         }
  1223.         // gdy jest niepoprawna tj mniejsza od 2
  1224.         else if(czy_jest_skala == -1)
  1225.         {
  1226.             printf("Plik ma niepoprawna skale\n");
  1227.         }
  1228.         // jesli nie istnieje
  1229.         else if(czy_jest_skala == -2)
  1230.         {
  1231.              printf("Plik nie ma podanej skali\n");
  1232.         }
  1233.     }
  1234.  
  1235.     // bledy sumarycznie
  1236.     int suma_bledow = czy_podano_wymiary + czy_jest_skala;
  1237.     if(jaki_jest_typ == -1) suma_bledow += jaki_jest_typ; // gdy nie bylo typu
  1238.     else                    suma_bledow += 0;             // gdy byl poprawny typ
  1239.     // gdy byl przynajmniej 1 blad
  1240.     if(suma_bledow != 0)
  1241.     {
  1242.         return -1;
  1243.     }
  1244.     // gdy wszystko jest w porzadku
  1245.     else
  1246.     {
  1247.         return 0;
  1248.     }
  1249. }
  1250.  
  1251. /*****************************************************************************************************************/
  1252. /*                                                 FUNKCJE POMOCNICZE                                            */
  1253. /*****************************************************************************************************************/
  1254.  
  1255. int czy_jest_cyfra(char znak)
  1256. {
  1257.     /*
  1258.         Dzialanie:
  1259.                   Sprawdza czy znak z argumentu jest jest cyfra
  1260.         Zwraca:
  1261.                 1 jest
  1262.                 0 nie jest
  1263.     */
  1264.     char cyfry[10] = {'0','1','2','3','4','5','6','7','8','9'};
  1265.  
  1266.     for (int i = 0; i < 10; i++)
  1267.     {
  1268.         // gdy zero
  1269.         if(znak == cyfry[i] && i == 0)
  1270.         {
  1271.             return 0;
  1272.         }
  1273.         // gdy inna cyfra
  1274.         else if(znak == cyfry[i] && i != 0)
  1275.         {
  1276.             return 1;
  1277.         }
  1278.  
  1279.     }
  1280.  
  1281.     return 0;
  1282. }
  1283.  
  1284. void pobierz_typ(FILE * plik, int * typ)
  1285. {
  1286.     /*
  1287.         Dzialanie:
  1288.             Pobiera 2 znak z 1 linii.
  1289.             W tym miejscu jest podany tym obrazu.
  1290.             Przypisuje go do zmiennej przekazanej przez argument.
  1291.  
  1292.     */
  1293.     char bufor[DL_LINII];
  1294.  
  1295.     rewind(plik);
  1296.     fgets(bufor, DL_LINII, plik);
  1297.  
  1298.     // typ to 2 znak z 1 linii
  1299.     *typ = atoi(bufor+1);
  1300.  
  1301.  
  1302. }
  1303.  
  1304. char** pobierz_komentarze(FILE * plik, int * ilosc_komentarzy)
  1305. {
  1306.  
  1307.     /*
  1308.         Dzialanie:
  1309.                 Przeszukuje plik w poszukiwaniu linii ze znakiem '#' na poczatku
  1310.                 Gdy taka linie znajdzie realokuje tablice z komentarzami i zapisuje
  1311.                 znaleziona linie.
  1312.                 Jednoczenie przypisuje wartosc zmiennej ilosc komentarzy
  1313.         Zwraca:
  1314.                 tablice 2d komentarzy
  1315.                 NULL jesli nie ma komentarzy
  1316.  
  1317.         UWAGA: UWOLNIC POTEM PAMIEC
  1318.     */
  1319.  
  1320.     char bufor[DL_LINII];
  1321.  
  1322.     char ** komentarze = NULL;
  1323.  
  1324.     *ilosc_komentarzy = 0;
  1325.  
  1326.     while(1)
  1327.     {
  1328.         char * czy_koniec = fgets(bufor, DL_LINII, plik);
  1329.  
  1330.         if(czy_koniec == NULL)
  1331.         {
  1332.             break;
  1333.         }
  1334.         // Gdy jest to 1 komentarz to alokuj tablice i wiersz oraz zapisz komentarz z buforu
  1335.         if(bufor[0] == '#' && (*ilosc_komentarzy) == 0)
  1336.         {
  1337.             // Zwieksz ilosc komentarzy
  1338.             (*ilosc_komentarzy)++;
  1339.             // alokuj 1 wiersz
  1340.             komentarze = (char**) malloc(sizeof(char*));
  1341.             // alokuj 1 linie
  1342.             *komentarze = (char*) malloc(sizeof(char) * DL_LINII);
  1343.             // przekopiuj komentarz z bufora
  1344.             strcpy(*komentarze, bufor);
  1345.         }
  1346.         // Gdy jest to kolejny komentarz odpowiednio reallokuj tablice, powieksz ja i go zapisz z buforu
  1347.         else if(bufor[0] == '#' && (*ilosc_komentarzy) !=0)
  1348.         {
  1349.             // zwieksz ilosc
  1350.             (*ilosc_komentarzy)++;
  1351.             // realokuj na 1 wieksza
  1352.             komentarze = realloc(komentarze, sizeof(char**) * (*ilosc_komentarzy));
  1353.             // alokuj nowa linie
  1354.             *(komentarze + (*ilosc_komentarzy) - 1) = (char*) malloc(sizeof(char) * DL_LINII);
  1355.             // przekopiuj do nowej linii komentarz z bufora
  1356.             strcpy(*(komentarze + (*ilosc_komentarzy) -1), bufor);
  1357.         }
  1358.     }
  1359.  
  1360.     return komentarze;
  1361. }
  1362.  
  1363. void pobierz_wymiary(FILE * plik, int * wysokosc, int * szerokosc)
  1364. {
  1365.     /*
  1366.         Dzialanie:
  1367.                     Funkcja ta opiera sie na formacie plikow.
  1368.                     PIERWSZA LINIA w ktorej PIERWSZY ZNAK jest CYFRA to linia z wymiarami tj.
  1369.                     PRZYKLAD:
  1370.                     Px
  1371.                     # jakies kometarze
  1372.                     100 100 <- pierwsza linia z cyfra jako 1 znak to wymiary
  1373.                     Gdy dojdziemy do tej linii ekstrahujemy z niej wymiary  i przypisujemy do zmiennych z argumentow
  1374.  
  1375.  
  1376.     */
  1377.  
  1378.     char bufor[DL_LINII];
  1379.     rewind(plik);           // na wszelki wypadek przewin
  1380.     int ktora_z_kolei = 0;  // okresla, z ktora linia, w ktorej pierwszym znakiem jest cyfra, mamy do czynienia
  1381.  
  1382.     while(1)
  1383.     {
  1384.         char * czy_koniec = fgets(bufor, DL_LINII, plik);
  1385.  
  1386.          // gdy 1 znak jest cyfra to funkcja zwraca 1(dla 1-9) lub 0(dla zera), gdy nie -1
  1387.         if(czy_jest_cyfra(bufor[0]) == 1)
  1388.         {
  1389.             ktora_z_kolei++;
  1390.         }
  1391.         if(czy_koniec == NULL)
  1392.         {
  1393.             break;
  1394.         }
  1395.         if(ktora_z_kolei == 1)
  1396.         {
  1397.             // gdy znaleziono 1 linie z cyframi to
  1398.             sscanf(bufor, "%d %d", szerokosc, wysokosc);
  1399.             break;
  1400.         }
  1401.     }
  1402. }
  1403.  
  1404. void pobierz_skale(FILE * plik, int * skala)
  1405. {
  1406.     /*
  1407.         Dzialanie:
  1408.                     Funkcja ta opiera sie na formacie plikow typu P2 i P3.
  1409.                     DRUGA LINIA w ktorej PIERWSZY ZNAK jest CYFRA to linia z odcieniami szarosci tj.
  1410.                     PRZYKLAD:
  1411.                     Px
  1412.                     # jakies kometarze
  1413.                     100 100 <- pierwsza linia z cyfra jako 1 znak to wymiary
  1414.                     1234    <- druga -||- to skala
  1415.                     Gdy dojdziemy do tej linii ekstrahujemy z niej skale i przypisujemy do zmiennej z argumentu
  1416.  
  1417.  
  1418.     */
  1419.  
  1420.     char bufor[DL_LINII];
  1421.     int ktora_z_kolei = 0;
  1422.  
  1423.     rewind(plik);   // na wszelki wypadek przewin
  1424.  
  1425.     while(1)
  1426.     {
  1427.         char * czy_koniec = fgets(bufor, DL_LINII, plik);
  1428.          // gdy 1 znak jest cyfra to funkcja zwraca 1(dla 1-9) lub 0(dla zera), gdy nie -1
  1429.         if(czy_jest_cyfra(bufor[0]) == 1)
  1430.         {
  1431.             ktora_z_kolei++;
  1432.         }
  1433.         if(czy_koniec == NULL)
  1434.         {
  1435.             break;
  1436.         }
  1437.         if(ktora_z_kolei == 2)
  1438.         {
  1439.             sscanf(bufor, "%d", skala);
  1440.             break;
  1441.         }
  1442.  
  1443.     }
  1444. }
  1445.  
  1446. int *** pobierz_piksele(FILE * plik, int wysokosc, int szerokosc, int typ)
  1447. {
  1448.     /*
  1449.         Dzialanie:
  1450.                     Zaleznie od typu pobiera z danego pliku piksele
  1451.                     Kazdy zestaw pikseli sklada sie z 4 dwuwymiarowych tablic intigerow, w ktorych
  1452.                     1 tablica to piksele czerwone   R
  1453.                     2 tablica to piksele zielone    G
  1454.                     3 tablica to piksele niebieskie B
  1455.                     4 tablica to piksele bialo czarne badz w odcieniach szarosci
  1456.  
  1457.                     Tablice 1-3 sa wypelniane gdy natrafimy na plik typu P3.
  1458.                     Tablica 4 pozostaje wtedy niewypelniana
  1459.  
  1460.                     Tablica 4 jest wypelniana gdy natrafimy na typ P1 lub P2.
  1461.                     Tablice 1-3 pozostaja wtedy niewypelniane
  1462.  
  1463.                     UWAGA: NALEZY NA KONIEC PRACY ZE ZDJECIEM ZWOLNIC WSZYSTKIE 4 TABLICE
  1464.  
  1465.                     TYP P1 Przyklad:
  1466.                     P1
  1467.                     # ewentualne komentarze
  1468.                     100 100 <- Pierwsza linia, w ktorej na poczatku jest cyfra [1-9] to na pewno wymiary
  1469.                     1 0...  <- Druga linia,    w ktorej na poczatku jest cyfra [0-1] to na pewno piksele
  1470.                     Gdy wykryje 1 linie z cyfra przestaje skanowac dalej plik a zaczyna pobieranie wartosci
  1471.                     danych pikseli i zapisywac je w piksele[4][x][y]
  1472.  
  1473.  
  1474.                     TYP P2 Przyklad:
  1475.                     P2
  1476.                     # ewentualne komentarze
  1477.                     100 100 <- Pierwsza linia, w ktorej na poczatku jest cyfra [1-9] to na pewno wymiary
  1478.                     1024    <- Druga linia,    w ktorej na poczatku jest cyfra [1-9] to na pewno skala szarosci
  1479.                     1 0...  <- Trzecia linia,  w ktorej na poczatku jest cyfra [0-1] to na pewno piksele
  1480.                     Gdy wykryje 1 linie z cyfra przestaje skanowac dalej plik a zaczyna pobieranie wartosci
  1481.                     danych pikseli i zapisywac je w piksele[4][x][y]
  1482.  
  1483.                     TYP P3 Przyklad:
  1484.                     P3
  1485.                     # ewentualne komentarze
  1486.                     100 100 <- Pierwsza linia, w ktorej na poczatku jest cyfra [1-9] to na pewno wymiary
  1487.                     1024    <- Druga linia,    w ktorej na poczatku jest cyfra [1-9] to na pewno skladowe kolorow
  1488.                     1 0...  <- Trzecia linia,  w ktorej na poczatku jest cyfra [0-1] to na pewno piksele
  1489.                     Gdy wykryje 1 linie z cyfra przestaje skanowac dalej plik a zaczyna pobieranie wartosci
  1490.                     danych pikseli.
  1491.                     Nastepnie przypisuje dane piksele trojkami do odpowiednich tablic tj
  1492.                     fscanf("%d %d %d", RED,              GREEN,            BLUE)
  1493.                     fscanf("%d %d %d", piksele[1][x][y], piksele[1][x][y], piksele[1][x][y])
  1494.         Kontrola bledow:
  1495.                     W chwili pobierania pikseli monitorujemy jaka ich ilosc udalo sie pobrac.
  1496.                     W przypadku obrazow typu P1 i P2 ilosc pikseli, ktore udalo sie pobrac powinna
  1497.                     byc rowna wysokosci * szerokosc.
  1498.                     Jesli tak nie jest funkcja zwroci NULL
  1499.                     W przypadku obrazow typu P3 dzialamy analogicznie jednakze, przy kazdej pobranej
  1500.                     trojce pikseli zwiekszamy ilosc pobranych o 3, a na koncu przyrownujemy do
  1501.                     3 * wysokosc * szerokosc.
  1502.         Zwraca:
  1503.  
  1504.                 Jesli sukces                    int ***
  1505.                 Jesli nie udalo sie wczytac     NULL
  1506.  
  1507.     */
  1508.  
  1509.    // Bufor pomocniczy do przewijania pliku
  1510.     char bufor[DL_LINII];
  1511.     // zmienna pomocnicza do liczenia pikseli, ktore udalo sie pobrac
  1512.     int ktora_z_kolei = 0;
  1513.  
  1514.  
  1515.     rewind(plik);   // na wszelki wypadek przewin
  1516.  
  1517.     /* trojwymiarowa tablica pikseli alokacja ---------------------------------------------------------*/
  1518.  
  1519.     int *** piksele = (int***) malloc(sizeof(int**) * 4); // zaalokuj 3 tablice dla RGB i jedna dla odcieni szarosci
  1520.     // zaalokuj odpowiednia wierszy w kazdej tablicy
  1521.     for(int tab = 0; tab < 4; tab++)
  1522.     {
  1523.         for(int wiersz = 0; wiersz < wysokosc; wiersz++)
  1524.         {
  1525.            *(piksele + tab) = (int**) malloc(sizeof(int*) * wysokosc);
  1526.         }
  1527.     }
  1528.  
  1529.  
  1530.     // zaalokuj odpowiednia ilosc kolumn w kazdej tablicy
  1531.     for(int tab = 0; tab < 4; tab++)
  1532.     {
  1533.         for(int wiersz = 0; wiersz < wysokosc; wiersz++)
  1534.         {
  1535.            *(*(piksele + tab) + wiersz) = (int*) malloc(sizeof(int) * szerokosc);
  1536.         }
  1537.     }
  1538.     /* trojwymiarowa tablica pikseli alokacja koniec --------------------------------------------------*/
  1539.  
  1540.  
  1541.     /* Przewin do miejsca gdzie znajduja sie piksele*/
  1542.     while(1)
  1543.     {
  1544.         char * czy_koniec = fgets(bufor, DL_LINII, plik);
  1545.  
  1546.         // gdy 1 znak jest cyfra to funkcja zwraca 1(dla 1-9) lub 0(dla zera), gdy nie -1
  1547.         if(czy_jest_cyfra(bufor[0]) == 1)
  1548.         {
  1549.             ktora_z_kolei++;
  1550.         }
  1551.         if(czy_koniec == NULL)
  1552.         {
  1553.             break;
  1554.         }
  1555.         // Jesli typ to P1 to w tym momencie mozna zakonczyc przewijanie gdyz 1 linia to wymiary
  1556.         // po ktorych znajduja sie piksele
  1557.         if(ktora_z_kolei == 1 && typ == 1)
  1558.         {
  1559.             break;
  1560.         }
  1561.         // Jesli typ to P2 lub P3 to po 2 linii, w ktorej jako 1 znak wystepuje cyfra(skala)
  1562.         // wystepuje piksele
  1563.         if(ktora_z_kolei == 2 && (typ == 2 || typ == 3))
  1564.         {
  1565.             break;
  1566.         }
  1567.     }
  1568.  
  1569.  
  1570.     if (typ == 1 || typ == 2)
  1571.     {
  1572.         /*
  1573.             Jezeli typ pliku to 1 albo 2 to pobieramy POJEDYNCZE wartosci dla kazdego piksela
  1574.             i zapisujemy w tablicy numer 4
  1575.         */
  1576.  
  1577.         int ile_pikseli_wczytano = 0;
  1578.         for(int wys = 0; wys < wysokosc; wys++)
  1579.         {
  1580.             for(int szer = 0; szer < szerokosc; szer++)
  1581.             {
  1582.                 // wczytuj i licz wczytane
  1583.                 if(fscanf(plik, "%d", &piksele[3][wys][szer]) == 1)
  1584.                 {
  1585.                     ile_pikseli_wczytano++;
  1586.                 }
  1587.  
  1588.             }
  1589.         }
  1590.  
  1591.         // gdy ilosc sie zgadza
  1592.         if(wysokosc*szerokosc == ile_pikseli_wczytano) return piksele;
  1593.         // gdy ilosc sie nie zgadza
  1594.         else                                           return NULL;
  1595.     }
  1596.  
  1597.     if(typ == 3)
  1598.     {
  1599.         /*
  1600.             Jezeli typ pliku to 3 to piksele zapisujemy w tablicach 1,2,3, ktore odpowiedaja R G B;
  1601.         */
  1602.  
  1603.         int ile_pikseli_wczytano = 0;
  1604.         for(int wys = 0; wys < wysokosc; wys++)
  1605.         {
  1606.             for(int szer = 0; szer < szerokosc; szer++)
  1607.             {
  1608.                 // wczytuj R G B i licz wczytane
  1609.                 if(fscanf(plik, "%d %d %d", &piksele[0][wys][szer], &piksele[1][wys][szer], &piksele[2][wys][szer]) == 3)
  1610.                 {
  1611.                     ile_pikseli_wczytano += 3;
  1612.                 }
  1613.  
  1614.             }
  1615.         }
  1616.  
  1617.         // gdy ilosc sie zgadza
  1618.         if(wysokosc*szerokosc*3 == ile_pikseli_wczytano) return piksele;
  1619.         // gdy ilosc sie nie zgadza
  1620.         else                                             return NULL;
  1621.  
  1622.     }
  1623.  
  1624.     return NULL;
  1625. }
  1626.  
  1627. void zwolnij_tablice_znakow(char ** tablica, int ilosc_wierszy)
  1628. {
  1629.  
  1630.     if(ilosc_wierszy != 0)
  1631.     {
  1632.         for(int i = 0; i< ilosc_wierszy; i++)
  1633.         {
  1634.             // kolumny
  1635.             free(*(tablica +i ));
  1636.             // i na koniec wiersze
  1637.             if(i + 1 == ilosc_wierszy) free(tablica);
  1638.         }
  1639.     }
  1640. }
  1641.  
  1642. void zwolnij_tablice_liczb(int ** tablica, int ilosc_wierszy)
  1643. {
  1644.  
  1645.     if(ilosc_wierszy != 0)
  1646.     {
  1647.         for(int i =0; i< ilosc_wierszy; i++)
  1648.         {
  1649.             // kolumny
  1650.             free(*(tablica +i ));
  1651.             // i na koniec wiersze
  1652.             if(i + 1 == ilosc_wierszy) free(tablica);
  1653.         }
  1654.     }
  1655. }
  1656.  
  1657. int czy_skala_jest_prawdziwa(int ** piksele, int skala, int wysokosc, int szerokosc)
  1658. {
  1659.     int minimum  = znajdz_minimum (piksele, wysokosc, szerokosc);
  1660.     int maksimum = znajdz_maksimum(piksele, wysokosc, szerokosc);
  1661.     // gdy realne wartosci przekraczaja zadeklarowane granice
  1662.     if(minimum < 0 || maksimum > skala)
  1663.     {
  1664.         printf("Realne minimum      = %d | Realne maksimum      = %d\n", minimum, maksimum);
  1665.         printf("Deklarowane minimum = %d | Deklarowane maksimum = %d\n", 0, skala - 1);
  1666.         return -1;
  1667.     }
  1668.     else return 0;
  1669.  
  1670. }
  1671.  
  1672. int ** normalizuj(int ** piksele, int skala, int wysokosc, int szerokosc)
  1673. {
  1674.     /*
  1675.         Dzialanie
  1676.                     Normalizuje zadana tablice liczb(pikseli) by byly w odpowiednim przedziale szarosci
  1677.                     Pozbywa sie elementow odstajacych (otlier)
  1678.         Zwraca:     Znormalizowana tablice
  1679.  
  1680.     */
  1681.  
  1682.  
  1683.     int minimum    = znajdz_minimum (piksele, wysokosc, szerokosc); // znajdz realne minimum
  1684.     int maksimum   = znajdz_maksimum(piksele, wysokosc, szerokosc); // znajdz realne maksimum
  1685.     // alokuj znormalizowana tablice
  1686.     int ** znormalizowana_tablica = (int**) malloc(sizeof(int*) * wysokosc);
  1687.     for(int i =0; i< szerokosc; i++)
  1688.     {
  1689.         *(znormalizowana_tablica + i) = (int*)malloc(sizeof(int) * szerokosc);
  1690.     }
  1691.  
  1692.     // wykonaj operacje
  1693.     for(int wys = 0; wys < wysokosc; wys++)
  1694.     {
  1695.         for(int szer = 0; szer < szerokosc; szer++)
  1696.         {
  1697.             // rzutowania na double bo na liczbach calkowitych nie da sie poprawnie wykonac takich dzialan
  1698.             // dziele na licznik i mianownik dla przejrzystosci
  1699.             double licznik   = (double)(piksele[wys][szer] - minimum) * (double) skala;
  1700.             double mianownik = (double)(maksimum - minimum);
  1701.             znormalizowana_tablica[wys][szer] = (int)(licznik / mianownik);
  1702.         }
  1703.     }
  1704.  
  1705.     return znormalizowana_tablica;
  1706. }
  1707.  
  1708. int znajdz_minimum(int ** piksele, int wysokosc, int szerokosc)
  1709. {
  1710.     int minimum = piksele[0][0];
  1711.     for(int i = 0; i < wysokosc; i++)
  1712.     {
  1713.         for(int e =0; e< szerokosc; e++)
  1714.         {
  1715.             if(piksele[i][e] < minimum)
  1716.             {
  1717.                 minimum = piksele[i][e];
  1718.             }
  1719.         }
  1720.     }
  1721.     return minimum;
  1722. }
  1723.  
  1724. int znajdz_maksimum(int ** piksele, int wysokosc, int szerokosc)
  1725. {
  1726.     int maksimum = piksele[0][0];
  1727.     for(int i = 0; i < wysokosc; i++)
  1728.     {
  1729.         for(int e = 0; e< szerokosc; e++)
  1730.         {
  1731.             if(piksele[i][e] > maksimum)
  1732.             {
  1733.                 maksimum = piksele[i][e];
  1734.             }
  1735.         }
  1736.     }
  1737.     return maksimum;
  1738. }
  1739.  
  1740. int ** negatyw(int ** piksele, int skala, int wysokosc, int szerokosc)
  1741. {
  1742.     /*
  1743.             Dzialanie:
  1744.                         Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
  1745.                         Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
  1746.             Zwraca:
  1747.                         Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
  1748.  
  1749.  
  1750.     */
  1751.     int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc); // (n)owe (piksele) - tablica wynikowa po operacji
  1752.  
  1753.     for(int i =0; i < wysokosc; i++)
  1754.     {
  1755.             *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
  1756.     }
  1757.  
  1758.     for(int i = 0; i < wysokosc; i++)
  1759.     {
  1760.         for(int e = 0; e < szerokosc; e++)
  1761.         {
  1762.             nowe_piksele[i][e] = skala - piksele[i][e];
  1763.         }
  1764.     }
  1765.     return nowe_piksele;
  1766. }
  1767.  
  1768. int ** progowanie(int ** piksele, int skala, int wysokosc, int szerokosc)
  1769. {
  1770.     /*
  1771.             Dzialanie:
  1772.                         Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
  1773.                         Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
  1774.             Zwraca:
  1775.                         Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
  1776.  
  1777.     */
  1778.  
  1779.     int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc); // (n)owe (piksele) - tablica wynikowa po operacji
  1780.     int prog_proc; // okresla jaki procent skali ma byc progiem
  1781.     int prog_wart; // wartosc progu jako liczba calkowita
  1782.  
  1783.     // pobierz wartosc procentowa progu i wylicz wartosc liczbowa
  1784.     printf("Podaj wartosc progu(procentowo): ");
  1785.     scanf("%d", &prog_proc);
  1786.     prog_wart = (prog_proc * skala) / 100;
  1787.  
  1788.     // zaalokuj potrzebna ilosc kolumn
  1789.     for(int i =0; i < wysokosc; i++)
  1790.     {
  1791.             *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
  1792.     }
  1793.  
  1794.     // oblicz nowa tablice
  1795.     for(int i = 0; i < wysokosc; i++)
  1796.     {
  1797.         for(int e = 0; e < szerokosc; e++)
  1798.         {
  1799.             // jesli powyzej progu to daj maksymalna wartosc szarosci piksela (bialy)
  1800.             if(piksele[i][e] > prog_wart)
  1801.             {
  1802.                 nowe_piksele[i][e] = skala - 1; // -1 bo majac ilosc odcieni np 255 najwyzsza jest 254
  1803.             }
  1804.             // jesli poniezej progu to daj minimalna wartosc szarosci piksela(czern)
  1805.             else
  1806.             {
  1807.                 nowe_piksele[i][e] = 0;
  1808.             }
  1809.         }
  1810.     }
  1811.     return nowe_piksele;
  1812. }
  1813.  
  1814. int ** polprogowanie_czerni(int ** piksele, int skala, int wysokosc, int szerokosc)
  1815. {
  1816.     /*
  1817.             Dzialanie:
  1818.                         Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
  1819.                         Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
  1820.             Zwraca:
  1821.                         Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
  1822.  
  1823.     */
  1824.     int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
  1825.     int prog_proc; // wartosc procentowa dla progu
  1826.     int prog_wart; // wartosc liczbowa
  1827.  
  1828.     // pobierz wartosc procentowa i przelicz na liczbowa
  1829.     printf("Podaj wartosc progu(procentowo): ");
  1830.     scanf("%d", &prog_proc);
  1831.     prog_wart = (prog_proc * skala) / 100;
  1832.  
  1833.     // alokuj kolumny
  1834.     for(int i =0; i < wysokosc; i++)
  1835.     {
  1836.         *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
  1837.     }
  1838.  
  1839.     // wykonaj operacje
  1840.     for(int i = 0; i < wysokosc; i++)
  1841.     {
  1842.         for(int e = 0; e < szerokosc; e++)
  1843.         {
  1844.             // powyzej progu zostaw wastosc
  1845.             if(piksele[i][e] > prog_wart)
  1846.             {
  1847.                 nowe_piksele[i][e] = piksele[i][e];
  1848.             }
  1849.             // ponizej progu daj minimalna wartosc(czern)
  1850.             else
  1851.             {
  1852.                 nowe_piksele[i][e] = 0;
  1853.             }
  1854.         }
  1855.     }
  1856.         return nowe_piksele;
  1857. }
  1858.  
  1859. int ** polprogowanie_bieli(int ** piksele, int skala, int wysokosc, int szerokosc)
  1860. {
  1861.     /*
  1862.             Dzialanie:
  1863.                         Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
  1864.                         Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
  1865.             Zwraca:
  1866.                         Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
  1867.  
  1868.     */
  1869.         int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
  1870.         int prog_proc; // wartosc procentowa progu
  1871.         int prog_wart; // wartosc liczbowa progu
  1872.  
  1873.         // pobierz wartosc procentowa i przelicz na liczbowa
  1874.         printf("Podaj wartosc progu(procentowo): ");
  1875.         scanf("%d", &prog_proc);
  1876.         prog_wart = (prog_proc * skala) / 100;
  1877.  
  1878.         // alokuj kolumny
  1879.         for(int i =0; i < wysokosc; i++)
  1880.         {
  1881.                 *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
  1882.         }
  1883.  
  1884.         // wykonaj operacje
  1885.         for(int i = 0; i < wysokosc; i++)
  1886.         {
  1887.             for(int e = 0; e < szerokosc; e++)
  1888.             {
  1889.                 // jesli ponizej progu to zostaw wartosc
  1890.                 if(piksele[i][e] <= prog_wart)
  1891.                 {
  1892.                     nowe_piksele[i][e] = piksele[i][e];
  1893.                 }
  1894.                 // jesli powyzej to daj maksymalna wartosc(biel)
  1895.                 else
  1896.                  {
  1897.                      nowe_piksele[i][e] = skala -1; // -1 bo majac np 255 odcieni szarosci maksymalna wartosc to 254
  1898.                  }
  1899.             }
  1900.         }
  1901.         return nowe_piksele;
  1902. }
  1903.  
  1904. int ** korekcja_gamma(int ** piksele, int skala, int wysokosc, int szerokosc)
  1905. {
  1906.     /*
  1907.             Dzialanie:
  1908.                         Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
  1909.                         Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
  1910.             Zwraca:
  1911.                         Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
  1912.  
  1913.     */
  1914.  
  1915.  
  1916.         double gamma; // wartosc parametru gamma
  1917.         int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
  1918.  
  1919.         // pobierz wartosc parametru gamma*10.0 i wylicz odpowiednia wartosc
  1920.         printf("Podaj wartosc parametru gamma(pomnozona przez 10 np. jesli chcesz 0.5 podaj 5):");
  1921.         scanf("%le", &gamma);
  1922.         gamma = gamma/10.0;
  1923.  
  1924.         // alokuj kolumny
  1925.         for(int i =0; i < wysokosc; i++)
  1926.         {
  1927.                 *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
  1928.         }
  1929.  
  1930.         // wykonaj operacje
  1931.         for(int i = 0; i < wysokosc; i++)
  1932.         {
  1933.             for(int e = 0; e < szerokosc; e++)
  1934.             {
  1935.                 // oblicza osobno liczni i mianownik dla uproszzcenia wyrazenia i przejrzystosci
  1936.                 double licznik   = pow((double) piksele[i][e],  1.0/ gamma);
  1937.                 double mianownik = pow((double) skala, (1.0 - gamma)/gamma);
  1938.                 nowe_piksele[i][e] = (int) licznik / mianownik;
  1939.             }
  1940.         }
  1941.  
  1942.     return nowe_piksele;
  1943.  
  1944. }
  1945.  
  1946. int ** zmiana_poziomow(int ** piksele, int skala, int wysokosc, int szerokosc)
  1947. {
  1948.      /*
  1949.             Dzialanie:
  1950.                         Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
  1951.                         Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
  1952.             Zwraca:
  1953.                         Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
  1954.  
  1955.     */
  1956.  
  1957.         // pobierz prog bieli i czerni
  1958.         int czern, biel;
  1959.         int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
  1960.  
  1961.         do
  1962.         {
  1963.             printf("Podaj wartosc progow czern/biel przedzielone przecinkiem \n");
  1964.             scanf("%d,%d", &czern, &biel);
  1965.         } while(!(czern > 0 && biel < skala)); // majac ilosc odcieni np 100 nie mozna dac progu bieli 101, a czerni -1,
  1966.                                                    // Ponadto prog czerni nie ma sensu gdy jest rowny 0
  1967.                                                    // gdyz wtedy ta operacja jest progowaniem czerni, ktore jest juz
  1968.                                                    // zaimplementowane w innej funkcji
  1969.  
  1970.         // alokuj kolumny
  1971.         for(int i = 0; i < wysokosc; i++)
  1972.         {
  1973.                 *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
  1974.         }
  1975.  
  1976.         // wykonaj operacje
  1977.         for(int i = 0; i < wysokosc; i++)
  1978.         {
  1979.             for(int e = 0; e < szerokosc; e++)
  1980.             {
  1981.                 // ponizej progu czerni ustaw na czern
  1982.                 if(piksele[i][e] < czern)
  1983.                 {
  1984.                     nowe_piksele[i][e] = 0;
  1985.                 }
  1986.                 // pomiedzy progiem czerni a bieli zostaw jak jest
  1987.                 else if(piksele[i][e] > czern && piksele[i][e] < biel)
  1988.                 {
  1989.                     nowe_piksele[i][e] = piksele[i][e];
  1990.                 }
  1991.                 // powyzej progu bieli ustaw na biel
  1992.                 else if(piksele[i][e] > biel)
  1993.                 {
  1994.                     nowe_piksele[i][e] = skala - 1; // -1 bo najwyzsza wartosc jest o 1 mniejsza niz ilosc odcieni szarosci
  1995.                 }
  1996.             }
  1997.         }
  1998.  
  1999.     return nowe_piksele;
  2000.  
  2001. }
  2002.  
  2003.  
  2004. int ** konturowanie(int ** piksele, int wysokosc, int szerokosc)
  2005. {
  2006.          /*
  2007.             Dzialanie:
  2008.                         Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
  2009.                         Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
  2010.             Zwraca:
  2011.                         Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
  2012.  
  2013.     */
  2014.  
  2015.  
  2016.         int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
  2017.  
  2018.         // zaalokuj kolumny
  2019.         for(int i =0; i < wysokosc; i++)
  2020.         {
  2021.                 *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
  2022.         }
  2023.         // wykonaj operacje
  2024.         for(int i = 1; i < wysokosc - 1; i++)
  2025.         {
  2026.             for(int e = 1; e < szerokosc - 1; e++)
  2027.             {
  2028.                 nowe_piksele[i][e] = abs(piksele[i+1][e] - piksele[i][e]) + abs(piksele[i][e+1] - piksele[i][e]);
  2029.             }
  2030.         }
  2031.  
  2032.     return nowe_piksele;
  2033.  
  2034. }
  2035.  
  2036. int ** rozmycie_poziome(int ** piksele, int wysokosc, int szerokosc)
  2037. {
  2038.      /*
  2039.             Dzialanie:
  2040.                         Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
  2041.                         Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
  2042.             Zwraca:
  2043.                         Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
  2044.  
  2045.     */
  2046.  
  2047.         int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
  2048.         // zaalokuj kolumny
  2049.         for(int i =0; i < wysokosc; i++)
  2050.         {
  2051.                 *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
  2052.         }
  2053.  
  2054.         // wykonaj operacje TODO dowolny promien v2
  2055.         for(int i = 1; i < wysokosc - 1; i++)
  2056.         {
  2057.             for(int e = 1; e < szerokosc - 1; e++)
  2058.             {
  2059.                 nowe_piksele[i][e] = (piksele[i][e+1] + piksele[i][e] + piksele[i][e+1]) / 3;
  2060.             }
  2061.         }
  2062.  
  2063.     return nowe_piksele;
  2064.  
  2065. }
  2066.  
  2067. int ** rozmycie_pionowe(int ** piksele, int wysokosc, int szerokosc)
  2068. {
  2069.          /*
  2070.                 Dzialanie:
  2071.                             Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
  2072.                             Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
  2073.                 Zwraca:
  2074.                             Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
  2075.  
  2076.         */
  2077.  
  2078.         int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
  2079.         // zaalokuj kolumny
  2080.         for(int i =0; i < wysokosc; i++)
  2081.         {
  2082.                 *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
  2083.         }
  2084.         // wykonaj operacje TODO dowolny promien v2
  2085.         for(int i = 1; i < wysokosc - 1; i++)
  2086.         {
  2087.             for(int e = 1; e < szerokosc - 1; e++)
  2088.             {
  2089.  
  2090.                 nowe_piksele[i][e] = (piksele[i+1][e] + piksele[i][e] + piksele[i-1][e]) / 3;
  2091.             }
  2092.         }
  2093.  
  2094.     return nowe_piksele;
  2095.  
  2096. }
  2097.  
  2098. int ** rozciagniecie_histogramu(int ** piksele, int skala, int wysokosc, int szerokosc)
  2099. {
  2100.      /*
  2101.             Dzialanie:
  2102.                         Wykonuje operacje na tablicy liczb pobranych jako 1 argument(pikseli)
  2103.                         Wynik dzialania na piksele[x][y] zapisuje w odpowiadajacym jej miejsci nowe_piksele[x][y]
  2104.             Zwraca:
  2105.                         Nowa tablice 2d liczb(pikseli), ktora nalezy przypisac do pikseli wyjsciowych
  2106.  
  2107.     */
  2108.  
  2109.         int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
  2110.         int minimum    = znajdz_minimum (piksele, wysokosc, szerokosc); // znajduje realne minimum w tablicy
  2111.         int maksimum   = znajdz_maksimum(piksele, wysokosc, szerokosc); // znajduje realne maksimum w tablicy
  2112.  
  2113.         for(int i =0; i < wysokosc; i++)
  2114.         {
  2115.                 *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
  2116.         }
  2117.  
  2118.         for(int i = 1; i < wysokosc - 1; i++)
  2119.         {
  2120.             for(int e = 1; e < szerokosc - 1; e++)
  2121.             {
  2122.                 nowe_piksele[i][e] = ((piksele[i][e] - minimum) * skala)/(maksimum - minimum);
  2123.             }
  2124.         }
  2125.  
  2126.     return nowe_piksele;
  2127.  
  2128. }
  2129.  
  2130. int ** operacje_z_uzyciem_masek(int ** piksele, int skala, int wysokosc, int szerokosc, int ** maska)
  2131. {
  2132.  
  2133.          // alokuj nowe piksele
  2134.  
  2135.          int ** nowe_piksele = (int**) malloc(sizeof(int*) * wysokosc);
  2136.          for(int i =0; i < wysokosc; i++)
  2137.          {
  2138.              *(nowe_piksele + i) = (int*) malloc(sizeof(int) * szerokosc);
  2139.  
  2140.          }
  2141.  
  2142.          // osobno piksele wynik z gornego, srodkowego i dolnego rzedu, by pojedyncza linia nie byla zbyt dluga
  2143.          for(int i = 1; i < wysokosc -1; i++)
  2144.          {
  2145.            for(int e = 1; e < szerokosc - 1; e++)
  2146.            {
  2147.                 int gorny_rzad    = maska[0][0] * piksele[i-1][e-1] + maska[0][1] * piksele[i-1][e] + maska[0][2] * piksele[i-1][e+1];
  2148.                 int srodkowy_rzad = maska[1][0] * piksele[i]  [e-1] + maska[1][1] * piksele[i]  [e] + maska[1][2] * piksele[i]  [e+1];
  2149.                 int dolny_rzad    = maska[2][0] * piksele[i+1][e-1] + maska[2][1] * piksele[i+1][e] + maska[2][2] * piksele[i+1][e+1];
  2150.                 int suma = gorny_rzad + srodkowy_rzad + dolny_rzad;
  2151.                 nowe_piksele[i][e] = suma;
  2152.             }
  2153.         }
  2154.  
  2155.         // normalizuj do wymaganego przedzialu( pozbywa sie elementow odstajacych(outlier))
  2156.         nowe_piksele = normalizuj(nowe_piksele, skala, wysokosc, szerokosc);
  2157.         return nowe_piksele;
  2158. }
  2159.  
  2160. int ** zwroc_zaalokowana_maske(int maska[3][3])
  2161. {
  2162.  
  2163.     // alokuj maske
  2164.     int ** maska_do_zwrocenia = (int**) malloc(sizeof(int*) * 3);
  2165.     for(int i = 0; i < 3; i++)
  2166.     {
  2167.         *(maska_do_zwrocenia + i) = (int*)malloc(sizeof(int) *3);
  2168.     }
  2169.  
  2170.     for(int i = 0; i < 3; i++)
  2171.     {
  2172.         for(int e = 0; e < 3; e++)
  2173.         {
  2174.             *(*(maska_do_zwrocenia + i) + e) = maska[i][e];
  2175.         }
  2176.     }
  2177.  
  2178.     return maska_do_zwrocenia;
  2179. }
  2180. int ** wybor_maski()
  2181. {
  2182.         // identycznosc na wypadek zlego wyboru maski
  2183.         int idn            [3][3] =  {{0,  0,  0},
  2184.                                       {0,  1,  0},
  2185.                                       {0,  0,  0}};
  2186.  
  2187.         // dolnoprzepustowe - redukcja lokalnych roznic jasnosci--------------------------------------------
  2188.         int usr            [3][3] =  {{1,  1,  1},
  2189.                                       {1,  1,  1},
  2190.                                       {1,  1,  1}};
  2191.  
  2192.         int usr_wzm        [3][3] =  {{1,  1,  1},
  2193.                                       {1,  2,  1},
  2194.                                       {1,  1,  1}};
  2195.         // gornoprzepustowe - wyodrebnianie kontury/krawedzie-----------------------------------------------
  2196.  
  2197.         //krawedzie
  2198.         int roberts        [3][3] =  {{ 0,  0,  0},
  2199.                                       {-1,  0,  0},
  2200.                                       { 0,  1,  0}};
  2201.         //linie poziome
  2202.         int prewit_poziom  [3][3] =  {{-1, -1, -1},
  2203.                                       { 0,  0,  0},
  2204.                                       { 1,  1,  1}};
  2205.         //linie pionowe
  2206.         int prewit_pion   [3][3] =   {{ 1,  0, -1},
  2207.                                       { 1,  0, -1},
  2208.                                       { 1,  0, -1}};
  2209.         // maski sobela - wyodrebnianie linii ---------------------------------------------------------------
  2210.  
  2211.         // poziomych
  2212.         int sobel_poziom  [3][3] = {{-1, -2, -1},
  2213.                                     { 0,  0,  0},
  2214.                                     { 1,  2,  1}};
  2215.         // pionowych
  2216.         int sobel_pion    [3][3] = {{-1,  0,  1},
  2217.                                     {-2,  0,  2},
  2218.                                     {-1,  0,  1}};
  2219.         // krawedzie i kontury naraz ------------------------------------------------------------------------
  2220.  
  2221.         int lapsjan1      [3][3] = {{ 1, -2,  1},
  2222.                                     {-2,  4, -2},
  2223.                                     { 1, -2,  1}};
  2224.  
  2225.         int lapsjan2      [3][3] = {{ 0, -1,  0},
  2226.                                     {-1,  4, -1},
  2227.                                     { 0,- 1,  0}};
  2228.  
  2229.         int lapsjan3      [3][3] = {{-1, -1, -1},
  2230.                                     {-1,  8, -1},
  2231.                                     {-1, -1, -1}};
  2232.  
  2233.         int wybor_maski;
  2234.         printf("Maski do wyboru:\n");
  2235.         printf("1.  Usredniajaca\n");
  2236.         printf("2.  Usredniajaca ze wzmocnieniem\n");
  2237.         printf("3.  Robertsa\n");
  2238.         printf("4.  Pozioma Prewita\n");
  2239.         printf("5.  Pionowa Prewita\n");
  2240.         printf("6.  Pozioma Sobela\n");
  2241.         printf("7.  Pionowa Sobela\n");
  2242.         printf("8.  Slaby  lapsjan\n");
  2243.         printf("9.  Sredni lapsjan\n");
  2244.         printf("10. Mocny  lapsjan\n");
  2245.         printf("11. Stworz wlasna maske\n");
  2246.         printf("Twoj wybor: ");
  2247.         scanf("%d", &wybor_maski);
  2248.         printf("|------------------------------------------------------|\n");
  2249.         switch(wybor_maski)
  2250.         {
  2251.             case 1:
  2252.                     return zwroc_zaalokowana_maske(usr);
  2253.                     break;
  2254.             case 2:
  2255.                     return zwroc_zaalokowana_maske(usr_wzm);
  2256.                     break;
  2257.             case 3:
  2258.                     return zwroc_zaalokowana_maske(roberts);
  2259.                     break;
  2260.             case 4:
  2261.                     return zwroc_zaalokowana_maske(prewit_poziom);
  2262.                     break;
  2263.             case 5:
  2264.                     return zwroc_zaalokowana_maske(prewit_pion);
  2265.                     break;
  2266.             case 6:
  2267.                     return zwroc_zaalokowana_maske(sobel_poziom);
  2268.                     break;
  2269.             case 7:
  2270.                     return zwroc_zaalokowana_maske(sobel_pion);
  2271.                     break;
  2272.             case 8:
  2273.                     return zwroc_zaalokowana_maske(lapsjan1);
  2274.                     break;
  2275.             case 9:
  2276.                     return zwroc_zaalokowana_maske(lapsjan2);
  2277.                     break;
  2278.             case 10:
  2279.                     return zwroc_zaalokowana_maske(lapsjan3);
  2280.                     break;
  2281.             case 11:
  2282.                     // tworzenie wlasnej maski
  2283.                     {
  2284.                        int wlasna[3][3];
  2285.  
  2286.                         printf("Prosze podac wartosci maski w formacie x,x,x \n");
  2287.                         for(int i = 0; i < 3; i++)
  2288.                         {
  2289.                             printf("Rzad numer %d:", i+1);
  2290.                             scanf("%d,%d,%d", &wlasna[i][0], &wlasna[i][1], &wlasna[i][2]);
  2291.                         }
  2292.                         return zwroc_zaalokowana_maske(wlasna);
  2293.                         break;
  2294.                     }
  2295.             default:
  2296.                     printf("Nieprawidlowy wybor maski. Zwracam identycznosc. \n((0 0 0)\n(0 1 0)\n(0 0 0)\n");
  2297.                     return zwroc_zaalokowana_maske(idn);
  2298.                     break;
  2299.  
  2300.         }
  2301. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement