Witam, mam problem. Mianowicie po odpaleniu programu w debuggerze i wybraniu 1 kroku następuje błąd w funkcji Zwolnij_Obraz, mianowicie program krzyczy że nie można odczytać pamięcie. Nie wiem czemu. Czy jest ktoś w stanie to wyjaśnić? Pozdrawiam
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <locale.h>
struct Obraz
{
int szerokosc, wysokosc;
int maxJasnosc;
int **dane;
char nazwa[20];
};
int Lepszy_Scanf();
void Zwolnij_Obraz(struct Obraz **);
struct Obraz *Alokacja(int, int);
int Wczytaj_Wartosc(FILE *);
struct Obraz * Wczytaj_Obraz();
void Dodaj_Obraz(struct Obraz ***, int *, struct Obraz *);
void Zapis_Obrazu(struct Obraz *);
void Drukuj_Liste_Obrazow(struct Obraz **, int);
struct Obraz * Wybor_Obrazu(struct Obraz **, int);
void Usun_Obraz(struct Obraz ***, int *);
void Zwolnij_Pamiec(struct Obraz **, int *);
struct Obraz * Odbicie_Wzg_X(struct Obraz *);
struct Obraz * Obrót_o_k90_stopni(struct Obraz *);
struct Obraz * Progowanie(struct Obraz *);
struct Obraz * Negatyw(struct Obraz *);
void Histogram (struct Obraz *);
struct Obraz * Pieprz_i_Sól(struct Obraz *);
struct Obraz * filtr(struct Obraz *);
int main()
{
struct Obraz *Foto = NULL;
struct Obraz **Tablica_do_obrazow = NULL;
int rozmiar_tab_do_obrazow = 0;
int menu = 1;
int menu_case1 = 1;
setlocale(LC_ALL, "Polish");
while (menu)
{
printf("0. Zamknij program\n1. Wczytanie obrazu i zapisanie do tablicy\n2. Lista obrazow\n3. Wybor aktywnego obrazu\n4. Usunięcie obrazu z listy\n5. Zapisanie obrazu w pliku\n6. Dodanie obrazu do listy\n7. Obicie względem osi X\n8. Obrót o 90*k stopni\n9. Progowanie obrazu\n10. Negatyw obrazu\n11. Histogram\n12. Szum pieprz i sól\n");
menu = Lepszy_Scanf();
{
switch (menu)
{
case 1:
system("cls");
Foto = Wczytaj_Obraz();
if (Foto != NULL) {
Dodaj_Obraz(&Tablica_do_obrazow, &rozmiar_tab_do_obrazow, Foto);
Zwolnij_Obraz(Foto);
printf("Wczytano obraz pomyślnie!\n");
printf("Dodano obraz do tablicy\n");
}
break;
case 2:
system("cls");
if (Tablica_do_obrazow != NULL) {
Drukuj_Liste_Obrazow(Tablica_do_obrazow, rozmiar_tab_do_obrazow);
}
else printf("BLAD! Lista obrazow jest pusta!\n\n");
break;
case 3:
system("cls");
if (Tablica_do_obrazow != NULL) {
Foto = Wybor_Obrazu(Tablica_do_obrazow, rozmiar_tab_do_obrazow);
}
else printf("Blad! Pusta lista!\n\n");
break;
case 4:
system("cls");
Usun_Obraz(&Tablica_do_obrazow, &rozmiar_tab_do_obrazow);
Foto = NULL;
break;
case 5:
system("cls");
Zapis_Obrazu(Foto);
break;
case 6:
system("cls");
if (Foto != NULL) {
Dodaj_Obraz(&Tablica_do_obrazow, &rozmiar_tab_do_obrazow, Foto);
printf("Dodano obraz do tablicy\n");
Foto = NULL;
}
break;
case 7:
system("cls");
Foto = Odbicie_Wzg_X(Foto);
if (Foto != NULL)
{
Dodaj_Obraz(&Tablica_do_obrazow, &rozmiar_tab_do_obrazow, Foto);
Foto = NULL;
printf("Odbito względem osi X\n");
printf("Dodano obraz do tablicy\n");
}
else
{
Zwolnij_Obraz(&Foto);
}
break;
case 8:
system("cls");
Foto = Obrót_o_k90_stopni(Foto);
if (Foto != NULL)
{
Dodaj_Obraz(&Tablica_do_obrazow, &rozmiar_tab_do_obrazow, Foto);
Foto = NULL;
printf("Obrócono obraz o 90*k stopni\n");
printf("Dodano obraz do tablicy\n");
}
else
{
Zwolnij_Obraz(&Foto);
}
break;
case 9:
system("cls");
Foto = Progowanie(Foto);
if (Foto != NULL)
{
Dodaj_Obraz(&Tablica_do_obrazow, &rozmiar_tab_do_obrazow, Foto);
Foto = NULL;
printf("Zprogowano obraz\n");
printf("Dodano obraz do tablicy\n");
}
else
{
Zwolnij_Obraz(&Foto);
}
break;
case 10:
system("cls");
Foto = Negatyw(Foto);
if (Foto != NULL)
{
Dodaj_Obraz(&Tablica_do_obrazow, &rozmiar_tab_do_obrazow, Foto);
Foto = NULL;
printf("Nałożono negatyw\n");
printf("Dodano obraz do tablicy\n");
}
else
{
Zwolnij_Obraz(&Foto);
}
break;
case 11:
system("cls");
Histogram(Foto);
break;
case 12:
system("cls");
Foto = Pieprz_i_Sól(Foto);
if (Foto != NULL)
{
Dodaj_Obraz(&Tablica_do_obrazow, &rozmiar_tab_do_obrazow, Foto);
Foto = NULL;
printf("Nałożono szum\n");
printf("Dodano obraz do tablicy\n");
}
else
{
Zwolnij_Obraz(&Foto);
}
break;
case 0:
system("cls");
if (Tablica_do_obrazow != NULL) {
Zwolnij_Pamiec(Tablica_do_obrazow, &rozmiar_tab_do_obrazow);
printf("Zwolniono pamiec\n");
}
printf("Koniec\n");
break;
default:
system("cls");
printf("Wybierz poprawny krok\n\n");
break;
}
}
}
}
int Lepszy_Scanf()
{
int liczba;
while (1)
{
if (!scanf("%d", &liczba))
{
while (getchar() != '\n');
printf("Sproboj ponownie\n");
}
else {
while (getchar() != '\n');
return liczba;
}
}
}
int Wczytaj_Wartosc(FILE *plik) {
int wartosc;
char tekst[2];
while (1)
{
if (fscanf(plik, "%d", &wartosc) == 1)
{
return wartosc;
}
if (fscanf(plik, "%1s", tekst) == 1 && tekst[0] == '#')
{
fscanf(plik, "%*[^\n]");
}
else
{
return -1;
}
}
}
void Zwolnij_Obraz(struct Obraz **obr)
{
int i;
if (*obr != NULL)
{
if ((*obr)->dane != NULL)
{
for (i = 0; i < (*obr)->wysokosc; ++i) {
free((*obr)->dane[i]);
}
free((*obr)->dane);
}
*obr = NULL;
}
}
struct Obraz *Alokacja(int wysokosc, int szerokosc)
{
struct Obraz *temp;
int i;
temp = (struct Obraz *)calloc(1, sizeof(struct Obraz));
if (temp != NULL)
{
temp->wysokosc = wysokosc;
temp->szerokosc = szerokosc;
temp->dane = calloc(wysokosc, sizeof(int*));
if (temp->dane != NULL)
{
for (i = 0; i<wysokosc; ++i)
{
temp->dane[i] = calloc(szerokosc, sizeof(int));
if (temp->dane[i] == NULL)
{
Zwolnij_Obraz(&temp);
return NULL;
}
}
}
else
{
Zwolnij_Obraz(&temp);
return NULL;
}
}
return temp;
}
struct Obraz * Wczytaj_Obraz()
{
char nazwa[15];
char id_standardu[3];
FILE *plik;
int wysokosc, szerokosc, jasnosc, x, y;
int blad = 0;
struct Obraz *obr;
printf("Podaj nazwe pliku:");
scanf("%19s", nazwa);
plik = fopen(nazwa, "rt");
if (plik != NULL)
{
if (fscanf(plik, "%2s", id_standardu) == 1 && id_standardu[0] == 'P' && (id_standardu[1] == '2' || id_standardu[1] == '5'))
{
wysokosc = Wczytaj_Wartosc(plik);
szerokosc = Wczytaj_Wartosc(plik);
jasnosc = Wczytaj_Wartosc(plik);
if (wysokosc>0 && szerokosc>0 && jasnosc>0)
{
obr = Alokacja(wysokosc, szerokosc);
if (obr != NULL)
{
obr->szerokosc = szerokosc;
obr->wysokosc = wysokosc;
obr->maxJasnosc = jasnosc;
strncpy(obr->nazwa, nazwa, 14);
for (x = 0; x<wysokosc; ++x)
{
for (y = 0; y<szerokosc; ++y)
{
obr->dane[x][y] = Wczytaj_Wartosc(plik);
if (obr->dane[x][y]<0)
{
Zwolnij_Obraz(&obr);
return NULL;
}
}
}
fclose(plik);
return obr;
}
blad = 1;
}
}
if (blad) printf("Bledny format pliku\n\n");
fclose(plik);
return NULL;
}
else
{
printf("Nie udalo sie otworzyc pliku %s\n\n", nazwa);
}
return NULL;
}
void Zapis_Obrazu(struct Obraz *obr) {
int i, j;
char nazwa_pliku[99];
FILE *plik;
if (obr != 0) {
printf("Podaj nazwe pliku\n");
scanf("%s", nazwa_pliku);
plik = fopen(nazwa_pliku, "wt");
if (plik != NULL)
{
fprintf(plik, "P2\n%d %d\n%d\n", obr->wysokosc, obr->szerokosc, obr->maxJasnosc);
for (i = 0; i < obr->wysokosc; ++i)
{
for (j = 0; j < obr->szerokosc; j++)
{
fprintf(plik, "%d", obr->dane[i][j]);
fprintf(plik, " ");
}
fprintf(plik, "\n");
}
printf("Zapisano pomyslnie\n\n");
fclose(plik);
}
}
else printf("Brak wybranego obrazu do zapisu, wybierz obraz z listy lub wczytaj z pliku\n\n");
}
void Dodaj_Obraz(struct Obraz *** Tablica_Obrazow, int *rozmiar, struct Obraz *obr) {
struct Obraz ** tab_tmp = NULL;
if (obr != NULL)
{
tab_tmp = realloc(*Tablica_Obrazow, (*rozmiar + 1) * sizeof(struct Obraz *));
if (tab_tmp != NULL) {
*Tablica_Obrazow = tab_tmp;
(*Tablica_Obrazow)[*rozmiar] = obr;
*rozmiar = *rozmiar + 1;
printf("OK\n");
}
}
else printf("BLAD\n");
}
void Drukuj_Liste_Obrazow(struct Obraz **tab, int rozmiar)
{
int i;
printf("lista obrazów \n");
for (i = 0; i < rozmiar; ++i)
{
printf("%d. %s \n", i, tab[i]->nazwa);
}
printf("\n");
}
struct Obraz * Wybor_Obrazu(struct Obraz **tab_obrazow, int rozmiar) {
int wybrany_indeks;
if (rozmiar != 0)
{
while (1)
{
Drukuj_Liste_Obrazow(tab_obrazow, rozmiar);
printf("wybierz indeks obrazu, wybranie ujemnego indeksu oznacza powrót do głównego menu\n");
wybrany_indeks = Lepszy_Scanf();
if (wybrany_indeks < 0) return NULL;
if (wybrany_indeks >= 0 && wybrany_indeks < rozmiar) {
printf("Wybrano pomyslnie\n\n");
return tab_obrazow[wybrany_indeks];
}
system("cls");
printf("BLAD! Wybierz liczbe z ponizszego zakresu\n\n");
}
}
else
{
printf("Brak obrazow\n\n");
return NULL;
}
}
void Usun_Obraz(struct Obraz ***tablica_obrazow, int *rozmiar) {
int wybrany_indeks;
int i;
if (*rozmiar > 0)
{
Drukuj_Liste_Obrazow(*tablica_obrazow, *rozmiar);
printf("Wybierz indeks obrazu do usunięcia, wybór ujemnego oznacza powrót do menu głównego\n");
wybrany_indeks = Lepszy_Scanf();
if (wybrany_indeks < 0) return;
if (wybrany_indeks >= 0 && wybrany_indeks < *rozmiar)
{
Zwolnij_Obraz(&((*tablica_obrazow)[wybrany_indeks]));
(*rozmiar) -= 1;
for (i = 0; i < *rozmiar; i++) {
(*tablica_obrazow)[wybrany_indeks] = (*tablica_obrazow)[wybrany_indeks + 1];
wybrany_indeks += 1;
}
*tablica_obrazow = realloc(*tablica_obrazow, sizeof(struct Obraz *)*(*rozmiar));
}
else printf("błedny indeks \n");
}
else printf("Pusta lista obrazow\n\n");
}
void Zwolnij_Pamiec(struct Obraz **tablica_obrazow, int *rozmiar) {
int i;
for (i = 0; i < *rozmiar; ++i)
{
Zwolnij_Obraz(&(tablica_obrazow)[i]);
}
free(*tablica_obrazow);
*tablica_obrazow = NULL;
*rozmiar = 0;
}
struct Obraz * Odbicie_Wzg_X(struct Obraz *obr) {
int y, x;
struct Obraz *tmp = NULL;
if (obr != NULL)
{
tmp = Alokacja(obr->wysokosc, obr->szerokosc);
tmp->maxJasnosc = obr->maxJasnosc;
sprintf(tmp->nazwa, "%s Odbity Wzg X", obr->nazwa);
if (tmp != NULL)
{
for (y = 0; y < obr->wysokosc; ++y)
{
for (x = 0; x < obr->szerokosc; ++x)
{
tmp->dane[obr->wysokosc - y - 1][x] = obr->dane[y][x];
}
}
printf("Odbito pomyslnie!\n");
return tmp;
}
printf("BLAD\n");
return NULL;
}
printf("Wczytaj obraz z pliku lub wybierz go najpierw z listy\n\n");
return NULL;
}
struct Obraz * Obrót_o_k90_stopni(struct Obraz *obr) {
int y, x, z;
int k = 0;
int flaga = 0;
struct Obraz *tmp = NULL;
if (obr != NULL)
{
printf("Podaj wartość krotności obrotu z zakresu od 1 do 3\n");
k = Lepszy_Scanf();
if (k < 1 && k > 3) {
k = Lepszy_Scanf();
}
if (k == 1) {
tmp = Alokacja(obr->szerokosc, obr->wysokosc);
tmp->maxJasnosc = obr->maxJasnosc;
sprintf(tmp->nazwa, "%s_Obrócony_o_90*%d_stopni", obr->nazwa, k);
if (tmp != NULL)
{
for (y = 0; y < obr->wysokosc; ++y)
{
for (x = 0; x < obr->szerokosc; ++x)
{
z = ((obr->wysokosc) - y - 1);
tmp->dane[x][z] = obr->dane[y][x];
}
}
printf("Udalo się obrócić obraz o %d*90 stopni\n\n", k);
return tmp;
}
}
if (k == 2) {
tmp = Odbicie_Wzg_X(obr);
printf("Udalo się obrócić obraz o %d*90 stopni\n\n", k);
return tmp;
}
if (k == 3) {
tmp = Alokacja(obr->szerokosc, obr->wysokosc);
tmp->maxJasnosc = obr->maxJasnosc;
sprintf(tmp->nazwa, "%s_Obrócony_o_90*%d_stopni", obr->nazwa, k);
if (tmp != NULL) {
while (flaga != 3) {
for (y = 0; y < obr->wysokosc; ++y)
{
for (x = 0; x < obr->szerokosc; ++x)
{
z = ((obr->wysokosc) - y - 1);
tmp->dane[x][z] = obr->dane[y][x];
}
}
flaga += 1;
}
printf("Udalo się obrócić obraz o %d*90 stopni\n\n", k);
return tmp;
}
}
printf("Blad, wybierz liczbę 1 , 2 albo 3\n");
return NULL;
}
printf("Wczytaj obraz z pliku lub wybierz go najpierw z listy\n\n");
return NULL;
}
struct Obraz * Progowanie(struct Obraz *obraz) {
int y, x;
int prog = 0;
struct Obraz *tmp = NULL;
if (obraz != NULL)
{
printf("Podaj próg progowania\n");
scanf("%d", &prog);
if (prog > 0 && prog < obraz->maxJasnosc) {
tmp = Alokacja(obraz->wysokosc, obraz->szerokosc);
tmp->maxJasnosc = obraz->maxJasnosc;
sprintf(tmp->nazwa, "%s_po_progowaniu", obraz->nazwa);
if (tmp != NULL)
{
for (y = 0; y < obraz->wysokosc; ++y)
{
for (x = 0; x < obraz->szerokosc; ++x)
{
if (obraz->dane[y][x] > prog) tmp->dane[y][x] = obraz->maxJasnosc;
else tmp->dane[y][x] = 0;
}
}
printf("Progowanie powiodlo się\n");
return tmp;
}
}
else printf("Nie podales wartosci progu z odopowiedniego dla danego obrazu przedzialu\n");
return NULL;
}
return NULL;
}
struct Obraz * Negatyw(struct Obraz *obraz) {
int y, x;
struct Obraz *tmp = NULL;
if (obraz != NULL)
{
tmp = Alokacja(obraz->wysokosc, obraz->szerokosc);
tmp->maxJasnosc = obraz->maxJasnosc;
sprintf(tmp->nazwa, "%s_negatyw", obraz->nazwa);
if (tmp != NULL)
{
for (y = 0; y < obraz->wysokosc; ++y)
{
for (x = 0; x < obraz->szerokosc; ++x)
{
tmp->dane[x][y] = obraz->maxJasnosc - obraz->dane[x][y];
}
}
printf("Udalo sie\n");
return tmp;
}
printf("Blad\n");
return NULL;
}
printf("Wybierz najpierw aktywny obraz\n");
return NULL;
}
void Histogram(struct Obraz *obraz) {
int y, x, i;
FILE *plik1;
int *hist;
if (obraz != NULL)
{
hist = (int*)calloc(obraz->maxJasnosc + 1, sizeof(int));
if (hist != NULL)
{
for (y = 0; y < obraz->wysokosc; ++y)
{
for (x = 0; x < obraz->szerokosc; ++x)
{
hist[obraz->dane[y][x]]++;
}
}
plik1 = fopen("histogram.csv", "wt");
if (plik1 != NULL)
{
for (i = 0; i < obraz->maxJasnosc; ++i)
fprintf(plik1, "%d; %d; \n", i, hist[i]);
fclose(plik1);
}
free(hist);
}
}
}
struct Obraz * Pieprz_i_Sól(struct Obraz *obraz)
{
int y, x, i, xx, yy;
int wybor;
srand(time(NULL));
struct Obraz *tmp = NULL;
if (obraz != NULL)
{
int Ilosc_Zaszumionych_Probek = 8;
tmp = Alokacja(obraz->wysokosc, obraz->szerokosc);
tmp->maxJasnosc = obraz->maxJasnosc;
for (xx = 0; xx < obraz->wysokosc; ++xx)
{
for (yy = 0; yy < obraz->szerokosc; ++yy)
{
tmp->dane[xx][yy] = obraz->dane[xx][yy];
}
}
sprintf(tmp->nazwa, "%s zaszumiony", obraz->nazwa);
if (tmp != NULL) {
for (i = 0; i < Ilosc_Zaszumionych_Probek; i++) {
x = rand() % tmp->szerokosc;
y = rand() % tmp->wysokosc;
if (rand() % 2)
{
wybor = tmp->maxJasnosc;
}
else
{
wybor = 0;
}
tmp->dane[x][y] = wybor;
}
printf("Udalo sie\n");
return tmp;
}
}
else printf("Blad, wybierz najpierw obraz\n");
}
struct Obraz * filtr(struct Obraz *obraz)
{
int y, z, x, c;
int xw = 0;
int yw = 0;
int suma = 0;
struct Obraz *tmp = NULL;
if (obraz != NULL)
{
tmp = Alokacja(obraz->wysokosc, obraz->szerokosc);
tmp->maxJasnosc = obraz->maxJasnosc;
sprintf(tmp->nazwa, "%s filtr", obraz->nazwa);
if (tmp != NULL)
{
for (y = 0; y < obraz->wysokosc; ++y)
{
for (x = 0; x < obraz->szerokosc; ++x)
{
for (z = y - 1; z < y + 1; ++z)
{
for (c = x - 1; c < x + 1; ++c)
{
if (c < 0) xw = 0;
else if (c > +obraz->szerokosc) xw = obraz->szerokosc - 1;
else xw = c;
if (z < 0) yw = 0;
else if (z > +obraz->wysokosc) yw = obraz->wysokosc - 1;
else yw = z;
suma = suma + obraz->dane[yw][xw];
}
}
tmp->dane[y][x] = (suma / 9);
}
}
printf("Udalo sie\n");
return tmp;
}
return NULL;
}
printf("Wybierz najpierw obraz z listy\n");
return NULL;
}