#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"); // Prüfe, ob die Datei mit dem richtigen String beginnt char *fileHeaderString = (char*)malloc(BUFFER_SIZE); fread(fileHeaderString, 1, (BUFFER_SIZE - 1), imageFile); if (strncmp(fileHeaderString, FILE_HEADER_STRING, 27)) { // Datei hat nicht das korrekte Format // Speicherplatz freigeben free(fileHeaderString); return NULL; } // Speicherplatz freigeben free(fileHeaderString); if (imageFile == NULL) { printf("Unbekannter Fehler, imageFile ist Null"); return NULL; } 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); //for (size_t i = 0; i < (itemsRead * 2); i++) { // printf("%02X ", bytestream[i]); //} if (itemsRead != 3) { // Nicht genügend Daten gelesen return -1; } // Anzahl der Bilder auslesen series->count = (unsigned int)bytestream[0] << 8 | bytestream[1]; // Breite der Bilder auslesen dimensionsOfImages[0] = (unsigned int)bytestream[2] << 8 | bytestream[3]; // Höhe der Bilder auslesen dimensionsOfImages[1] = (unsigned int)bytestream[4] << 8 | bytestream[5]; return 0; } static int getGrayScalePixelOfImage(FILE* imageFile, GrayScaleImage* image) { // SPeicher für Buffer allokieren image->buffer = malloc(image->width * image->height * sizeof(GrayScalePixelType)); // Pixelwerte aus Datei auslesen int itemsRead = fread(image->buffer, 1, image->width * image->height * sizeof(GrayScalePixelType), imageFile); if (itemsRead != image->width * image->height) { free(image->buffer); return -1; } return 0; } static unsigned 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."); } // 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 bei malloc"); return NULL; } for (int i = 0; i < series->count; i++) { // image initialisieren GrayScaleImage *image = NULL; image = (GrayScaleImage *)malloc(sizeof(GrayScaleImage)); image->width = dimensionsOfImages[0]; image->height = dimensionsOfImages[1]; if(getGrayScalePixelOfImage(imageFile, image) != 0) { printf("Fehler bei getGrayScalePixelOfImage"); } series->labels[i] = getLabelOfImage(imageFile, image); if (series->labels[i] == -1) { printf("Fehler bei getLabelOfImage"); } } // 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 return series; } // TODO Vervollständigen Sie die Funktion clearSeries, welche eine Bildserie vollständig aus dem Speicher freigibt void clearSeries(GrayScaleImageSeries *series) { }