diff --git a/imageInput.c b/imageInput.c index 47e78a3..5294301 100644 --- a/imageInput.c +++ b/imageInput.c @@ -2,54 +2,54 @@ #include #include #include "imageInput.h" - + #define BUFFER_SIZE 100 #define FILE_HEADER_STRING "__info2_image_file_format__" #define HEADER_LEN (sizeof(FILE_HEADER_STRING) - 1) //-1, um \0 Character rauszufiltern - + // TODO Implementieren Sie geeignete Hilfsfunktionen für das Lesen der Bildserie aus einer Datei - + static int checkDimensions(unsigned int width, unsigned int height){ - + int ok = 0; - + if(width > 0 && height > 0) return ok = 1; - - else - return ok = 0; - -} - -static int checkHeader(const GrayScalePixelType *buffer){ - - int ok = 0; - char header[HEADER_LEN + 1]; //Array mit Platz für Header Länge + \0 Character -> String - - // Jeder Byte in String kopieren - for(int i = 0; i < HEADER_LEN; i++){ - - header[i] = buffer[i]; - - } - - header[HEADER_LEN] = '\0'; // Nullterminator am Ende anhängen - - if(strcmp(header, FILE_HEADER_STRING) == 0) // wenn beide identische sind gibt cmp 0 zurück - return ok = 1; - + else return ok = 0; - + } - - + +static int checkHeader(const GrayScalePixelType *buffer){ + + int ok = 0; + char header[HEADER_LEN + 1]; //Array mit Platz für Header Länge + \0 Character -> String + + // Jeder Byte in String kopieren + for(int i = 0; i < HEADER_LEN; i++){ + + header[i] = buffer[i]; + + } + + header[HEADER_LEN] = '\0'; // Nullterminator am Ende anhängen + + if(strcmp(header, FILE_HEADER_STRING) == 0) // wenn beide identische sind gibt cmp 0 zurück + return ok = 1; + + else + return ok = 0; + +} + + static FILE *openImageFile(const char *path) { - return fopen(path, "rb"); - + return fopen(path, "rb"); + } - + static int ReadCheckHeader(FILE *fp, GrayScalePixelType *header) { if(fread(header, sizeof(GrayScalePixelType), HEADER_LEN, fp) != HEADER_LEN) @@ -58,67 +58,67 @@ static int ReadCheckHeader(FILE *fp, GrayScalePixelType *header) } return 1; } - + static int readMetaData(FILE *fp, unsigned int *numImages, unsigned int *width, unsigned int *height) { if(fread(numImages, sizeof(unsigned int), 1, fp) != 1 || fread(width, sizeof(unsigned int), 1, fp) != 1 || fread(height, sizeof(unsigned int), 1, fp)!= 1) { return 0; } - + return 1; } - + static GrayScaleImageSeries *allocateSeriesStruct(void) { GrayScaleImageSeries *series = malloc(sizeof(GrayScaleImageSeries)); return series; } - + static int AllocateCheckImageAndLabels(GrayScaleImageSeries *series, unsigned int numImages) { series->count = numImages; //Speicher für die Pointer an sich belegen series->images = malloc(numImages * sizeof(GrayScaleImage)); //Speicher für alle Bild-Strukturen, nicht aber für die Pixel selbst (denn image ist nochmal ein Array selbst) series->labels = malloc(numImages * sizeof(unsigned char)); //Speicher für alle Labels - + //Prüfen, ob Speicher für die Arrays reserviert werden konnte, wenn nicht -> Freigabe if(series->images == NULL || series->labels == NULL){ - + free(series->images); //wenn trotzdem was reingeschrieben wurde, dann freigeben free(series->labels); free(series); return 0; - + } - + return 1; } - + static int AllocateCheckPixelData(GrayScaleImageSeries *series, unsigned int numImages, unsigned int width, unsigned int height) { for(unsigned int i = 0; i < numImages; i++){ - + series -> images[i].buffer = malloc(width * height); //Speicher für Pixeldaten selbst - - if(series->images[i].buffer == NULL){ - + + if(series->images[i].buffer == NULL){ + for(unsigned int j = 0; j < i; j++){ free(series->images[j].buffer); //wenn Speicher nicht reserviert werden konnte, dann zuerst das Array mit Pixeldaten freigeben } - - + + free(series->images); //anschließend auch die Speicher für Bildstrukturen und Label-Arrays freigeben, weil zuvor für diese schon Speicher reserviert wurde free(series->labels); free(series); - - return 0; + + return 0; } } - + return 1; } - + static int ReadImagesAndLabels(FILE *fp, GrayScaleImageSeries *series, unsigned int numImages, unsigned int width, unsigned int height) { for(int i = 0; i < numImages; i++) @@ -126,118 +126,119 @@ static int ReadImagesAndLabels(FILE *fp, GrayScaleImageSeries *series, unsigned //Breite und Höhe werden gesetzt (GrayScaleImage) series -> images[i].width = width; series -> images[i].height = height; - - + + //Pixeldaten einlesen und Prüfen ob alle essentiellen Pixel eingelesen wurden if(fread(series -> images[i].buffer, 1, width * height, fp) != (width * height)) { clearSeries(series); return 0; } - + //Jedes Bild hat ein Label, was direkt danach eingelesen wird und auf Größe geprüft wird if(fread(&series -> labels[i], 1, 1, fp) != 1){ clearSeries(series); return 0; } } - + return 1; } - - - - - - - - - + + + + + + + + + // TODO Vervollständigen Sie die Funktion readImages unter Benutzung Ihrer Hilfsfunktionen GrayScaleImageSeries *readImages(const char *path) { GrayScaleImageSeries *series = NULL; - + //Datei im Binärmodus öffnen FILE *fp = openImageFile(path); if(!fp) return NULL; - - //Buffer zum Einlesen des Headers + + //Buffer zum Einlesen des Headers GrayScalePixelType header[HEADER_LEN]; - - //Prüfen, ob genau die HEADER_LEN Bytes eingelesen werden + + //Prüfen, ob genau die HEADER_LEN Bytes eingelesen werden if(!ReadCheckHeader(fp, header)){ fclose(fp); return NULL; } - + //Prüfen, ob es sich um den korrekten Header handelt mit Hilfsfunktion if(!checkHeader(header)){ fclose(fp); return NULL; } - - //Anzahl der Bilder, Breite und Höhe einlesen + + //Anzahl der Bilder, Breite und Höhe einlesen unsigned int numImages, width, height; //muss man das als Zeiger initialisieren????????? if(!readMetaData(fp, &numImages, &width, &height)){ fclose(fp); return NULL; } - - + + //Prüfen, ob gültige Länge oder Breite if(!checkDimensions(width, height)){ fclose(fp); return NULL; } - + //Speicher für die gesamte Bildserie reservieren (aber nur für die Struktur) series = allocateSeriesStruct(); if(!series) { fclose(fp); - return NULL; //Fehler bei Speicherreservierung + return NULL; //Fehler bei Speicherreservierung } - + if(!AllocateCheckImageAndLabels(series, numImages)){ fclose(fp); return NULL; } - - - //Speicher für die Pixeldaten selbst reserviern und Prüfen, ob er reserviert werden konnte + + + //Speicher für die Pixeldaten selbst reserviern und Prüfen, ob er reserviert werden konnte if(!AllocateCheckPixelData(series, numImages, width, height)){ - + fclose(fp); return NULL; - + } - - + + if(!ReadImagesAndLabels(fp, series, numImages, width, height)){ fclose(fp); return NULL; } - - fclose(fp); + + fclose(fp); return series; } - + // TODO Vervollständigen Sie die Funktion clearSeries, welche eine Bildserie vollständig aus dem Speicher freigibt void clearSeries(GrayScaleImageSeries *series) { if (series == NULL){ return; } - + for(unsigned int i = 0; i < series->count; i++){ - - free(series->images[i].buffer); + + free(series->images[i].buffer); } - - - free(series->images); + + + free(series->images); free(series->labels); free(series); -} \ No newline at end of file +} + \ No newline at end of file