#include #include #include #include "imageInput.h" #define BUFFER_SIZE 100 #define FILE_HEADER_STRING "__info2_image_file_format__" // Lädt eine .info2-Datei und prüft, ob das Dateiformat korrekt ist static FILE* openImageFile(const char* path) { FILE* imageFile = NULL; imageFile = fopen(path, "rb"); if (imageFile == NULL) { // Fehler beim Öffnen return NULL; } // Prüfe, ob die Datei mit dem richtigen String beginnt char *fileHeaderString = (char*)malloc(BUFFER_SIZE); fread(fileHeaderString, 1, strlen(FILE_HEADER_STRING), imageFile); if (strncmp(fileHeaderString, FILE_HEADER_STRING, 27)) { // Datei hat nicht das korrekte Format // Speicherplatz freigeben free(fileHeaderString); fclose(imageFile); return NULL; } // Speicherplatz freigeben free(fileHeaderString); return imageFile; } static int getInformationOfImages(FILE* imageFile, int dimensionsOfImages[], GrayScaleImageSeries *series) { // Speicher für die drei Zahlen (je Zahl 2 Byte) unsigned char bytestream[6]; // Daten einlesen int itemsRead = fread(bytestream, 2, 3, imageFile); if (itemsRead != 3) { // Nicht genügend Daten gelesen return -1; } // Anzahl der Bilder auslesen series->count = (unsigned int)bytestream[1] << 8 | bytestream[0]; // Breite der Bilder auslesen dimensionsOfImages[0] = (unsigned int)bytestream[3] << 8 | bytestream[2]; // Höhe der Bilder auslesen dimensionsOfImages[1] = (unsigned int)bytestream[5] << 8 | bytestream[4]; return 0; } static int getGrayScalePixelOfImage(FILE* imageFile, GrayScaleImage* image) { // SPeicher für Buffer allokieren image->buffer = malloc(image->width * image->height); size_t expectedItems = (size_t)image->width * image->height; // Anzahl der Pixel/Bytes // Pixelwerte aus Datei auslesen int itemsRead = fread(image->buffer, sizeof(GrayScalePixelType), expectedItems, imageFile); if (itemsRead != expectedItems) { free(image->buffer); return -1; } return 0; } static char getLabelOfImage(FILE* imageFile, GrayScaleImage* image) { // Array um Label zu speichern unsigned char *bytestream = malloc(1); // Label aus Datei auslesen int itemsRead = fread(bytestream, 1, 1, imageFile); if (itemsRead != 1) { free(bytestream); return -1; } unsigned char label = bytestream[0]; free(bytestream); return label; } GrayScaleImageSeries *readImages(const char *path) { // Datei laden und Dateiformat prüfen FILE* imageFile = openImageFile(path); if (imageFile == NULL) { printf("Unbekannter Fehler, imageFile ist Null"); return NULL; } // series initialisieren GrayScaleImageSeries *series = NULL; series = (GrayScaleImageSeries *)malloc(sizeof(GrayScaleImageSeries)); // Lies folgende Informationen aus der Datei aus: // 1) Anzahl der Bilder --> GreyScaleImageSeries.count // 2) Breite der Bilder --> width // 3) Höhe der Bilder --> height int dimensionsOfImages[2]; int erfolg = getInformationOfImages(imageFile, dimensionsOfImages, series); if (erfolg == -1) { printf("Unbekannter Fehler bei getInformationOfImages."); fclose(imageFile); return NULL; } // Speicher für die Labels vorbereiten, wird später Bild für Bild befüllt series->labels = malloc(series->count * sizeof(unsigned char)); // labels = unsigned char-Array mit der Größe wie AnzahlBilder if (series->labels == NULL) { printf("Fehler: Speicherzuweisung für labels fehlgeschlagen.\n"); free(series); fclose(imageFile); return NULL; } // Speicher für das Array von GrayScaleImage-Strukturen vorbereiten series->images = malloc(series->count * sizeof(GrayScaleImage)); if (series->images == NULL) { printf("Fehler: Speicherzuweisung für images fehlgeschlagen.\n"); free(series->labels); // Zuerst labels freigeben free(series); fclose(imageFile); return NULL; } for (int i = 0; i < series->count; i++) { // image initialisieren GrayScaleImage *image = &series->images[i]; // image = (GrayScaleImage *)malloc(sizeof(GrayScaleImage)); image->width = dimensionsOfImages[0]; image->height = dimensionsOfImages[1]; image->buffer = NULL; // Graustufe-Pixel lesen und im image speichern if(getGrayScalePixelOfImage(imageFile, image) != 0) { printf("Fehler: Konnte Pixel des Bildes %d nicht lesen.\n", i + 1); fclose(imageFile); clearSeries(series); return NULL; } // label lesen und in der series an entsprechender Stelle speichern int labelResult = getLabelOfImage(imageFile, image); if (labelResult == -1) { printf("Fehler: Konnte Label des Bildes %d nicht lesen.\n", i); fclose(imageFile); clearSeries(series); return NULL; } series->labels[i] = (unsigned char)labelResult; if (series->images == NULL) { printf("Fehler bei malloc für images"); free(series->labels); // Labels freigeben free(series); // Serie freigeben return NULL; } } fclose(imageFile); return series; } void clearSeries(GrayScaleImageSeries *series) { //prüfen, ob series überhaupt bereinigt werden muss if(series == NULL){ return; } //images freigeben und NULL setzen -> jeden Index der Images durchgehen und buffer freigeben if(series->images != NULL){ for(unsigned int i = 0; i < series->count; i++){ if (series->images[i].buffer != NULL){ free(series->images[i].buffer); series->images[i].buffer = NULL; } } free(series->images); // wenn alle images bereinigt sind, den Zeiger Images selbst bereinigen series->images = NULL; } //labels freigeben und NULL setzen if(series->labels != NULL){ free(series->labels); series->labels = NULL; } //series freigeben free(series); }