#include #include #include #include "imageInput.h" #define BUFFER_SIZE 100 #define FILE_HEADER_STRING "__info2_image_file_format__" // TODO Implementieren Sie geeignete Hilfsfunktionen für das Lesen der Bildserie aus einer Datei // 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; } // TODO Vervollständigen Sie die Funktion readImages unter Benutzung Ihrer Hilfsfunktionen GrayScaleImageSeries *readImages(const char *path) { // Datei laden und Dateiformat prüfen // setzt außerdem den Pointer an der Stelle nach dem Prestring 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; } } // für jedes Bild gemäß GreyScaleImageSeries.count: // GreyScaleImage.width = width // GreyScaleImage.height = height // GreyScaleImageSeries.buffer = Pixelwerte // labels = Label des Bilds // series.labels[i] = (unsigned char)(i % 256); // Springe in der Datei an die Stelle nach dem i. Bild fclose(imageFile); return series; } // TODO Vervollständigen Sie die Funktion clearSeries, welche eine Bildserie vollständig aus dem Speicher freigibt void clearSeries(GrayScaleImageSeries *series) { }