Witam, mam do napisania taką funkcję:
Wczytanie obrazu
struct img_t* load_image(const char* fname, enum error_code_t* errorCode);
Funkcja load_image odczytuje z pliku binarnego o nazwie fname obraz w formacie PGM (Portable Gray Map) i zapisuje jego zawartość w postaci alokowanej dynamicznie tablicy dwuwymiarowej do struktury img_t. Funkcja zwraca wczytany obraz wraz z jego wymiarami zapisanymi w strukturze img_t, a w przypadku błędu zwraca NULL oraz zapisuje kod błędu do zmiennej errorCode (brak przekazania parametru errorCode powinien skutkować natychmiastowym zakończeniem działania funkcji).
Plik PGM to obraz w skali szarości zapisany w formacie przenośnej szarej mapy (PGM), gdzie każdy piksel jest zakodowany jednym bajtem (8 bitów). Obraz składa się z siatki liczb reprezentujących różne odcienie szarości, z zakresu od czerni (0) do bieli (255). Pliki PGM mogą być przechowywane w formacie tekstowym ASCII lub binarnym.
Nagłówek pliku składa się z dwóch bajtów, które zawierają informację o formacie binarnym PGM - "P2". Następnie na kolejnych 8 bajtach zapisane są informacje o szerokości i wysokości obrazu, z każdą wartością zapisaną na 4 bajtach. Po tych danych następuje jeden bajt, w którym zapisana jest maksymalna wartość, jaką piksele mogą przyjąć.
Każdy piksel obrazu jest zapisany na 1 bajcie, a wartość każdego bajtu odpowiada konkretnemu odcieniowi szarości. W ten sposób, dla obrazu o wymiarach n x m, plik PGM ma długość (2 + 8 + 1 + n x m) bajtów.
Wartość zwracana
Kody błędu
ERROR_CODE_OK - w przypadku powodzenia.
ERROR_CODE_INCORRECT_PARAMETERS - w przypadku przekazania do funkcji nieprawidłowych danych.
ERROR_CODE_FILE_NOT_EXISTS - gdy plik o podanej nazwie nie istnieje.
ERROR_CODE_FILE_CORRUPTED - gdy plik ma niepoprawny format lub zawiera błędy.
ERROR_CODE_FAILED_TO_ALLOCATE_MEMORY - w przypadku niepowodzenia alokacji pamięci.
Wymagania pamięciowe
Funkcja nie może zaalokować więcej pamięci niż jest to niezbędne do posiadania w pamięci obrazu wczytanego z pliku.
Funkcja napisana przeze mnie wygląda następująco:
enum error_code_t{
ERROR_CODE_OK=0,
ERROR_CODE_INCORRECT_PARAMETERS=1,
ERROR_CODE_FILE_NOT_EXISTS=2,
ERROR_CODE_FILE_CORRUPTED=3,
ERROR_CODE_COULDNT_CREATE_FILE=4,
ERROR_CODE_FAILED_TO_ALLOCATE_MEMORY=5,
};
struct img_t
{
uint8_t **img;
int width;
int height;
};
void destroy_img(struct img_t *input){
if(input==NULL) return;
if(input->img!=NULL){
for(int i=0; *(input->img+i)!=NULL; i++)
free(*(input->img+i));
free(input->img);
}
free(input);
}
struct img_t *load_image(const char *fname, enum error_code_t *errorCode) {
if (fname == NULL || errorCode == NULL) {
*errorCode = ERROR_CODE_INCORRECT_PARAMETERS;
return NULL;
}
FILE *fp = fopen(fname, "rb");
if (fp == NULL) {
*errorCode = ERROR_CODE_FILE_NOT_EXISTS;
return NULL;
}
char *c;
c = calloc(3, sizeof(char));
if (fread(c, sizeof(char), 2, fp) != 2 || *c != 'P' && *(c + 1) != '2') {
*errorCode = ERROR_CODE_FILE_CORRUPTED;
free(c);
fclose(fp);
return NULL;
}
free(c);
int width, height;
if (fscanf(fp, "%d %d", &width, &height) != 2 || width < 0 || height < 0) {
*errorCode = ERROR_CODE_FILE_CORRUPTED;
fclose(fp);
return NULL;
}
unsigned char max_value;
int a;
if (fscanf(fp, "%hhu", &max_value) != 1) {
*errorCode = ERROR_CODE_FILE_CORRUPTED;
fclose(fp);
return NULL;
}
a=(int) max_value;
if(a>255){
*errorCode = ERROR_CODE_FILE_CORRUPTED;
fclose(fp);
return NULL;
}
struct img_t *image = NULL;
image = (struct img_t *) calloc(1, sizeof(struct img_t *));
if (image == NULL) {
*errorCode = ERROR_CODE_FAILED_TO_ALLOCATE_MEMORY;
fclose(fp);
return NULL;
}
image->img = (uint8_t **) calloc(height, sizeof(uint8_t *));
if (image->img == NULL){
*errorCode = ERROR_CODE_FAILED_TO_ALLOCATE_MEMORY;
fclose(fp);
destroy_img(image);
//free(image);
return NULL;
}
for (int i = 0; i < height; i++)
{
*(image->img + i) = (uint8_t *) calloc(width, sizeof(uint8_t));
if(*(image->img + i)==NULL){
*errorCode = ERROR_CODE_FAILED_TO_ALLOCATE_MEMORY;
fclose(fp);
destroy_img(image);
return NULL;
}
}
image->height = height;
image->width = width;
unsigned char val;
for(int i=0; i<height; i++){
for(int j=0; j<width; j++){
if(fscanf(fp, "%hhu", &val)!=1){
*errorCode = ERROR_CODE_FILE_CORRUPTED;
fclose(fp);
destroy_img(image);
return NULL;
}
a=(int)val;
if(a<0||a>255){
*errorCode = ERROR_CODE_FILE_CORRUPTED;
fclose(fp);
destroy_img(image);
return NULL;
}
*((*image->img+i)+j)=(int)val;
}
}
*errorCode = ERROR_CODE_OK;
return image;
}
Mój problem polega na tym, że za każdym razem przy odczytywaniu z pliku binarnego wysokości i szerokości funkcja zwraca NULL, czyli jest to błędnie odczytane. W przypadku plików txt nie mam takiego problemu, te dwie zmienne odczytują się poprawnie. Byłabym wdzięczna, za wskazówki gdzie popełniam błąd.
Z góry dziękuję