#include #include #include #include "imageInput.h" #define BUFFER_SIZE 100 #define FILE_HEADER_STRING "__info2_image_file_format__" // Hilfsfunktion: File Header überprüfen static int checkFileHeader(FILE* f) { char buffer[BUFFER_SIZE]; size_t len = strlen(FILE_HEADER_STRING); if (fread(buffer, 1, len, f) != len) { return -1; // Fehler beim Lesen } buffer[len] = '\0'; return strcmp(buffer, FILE_HEADER_STRING) == 0 ? 0 : -1; } // Hilfsfunktion: Metadaten lesen (Anzahl, Breite, Höhe) static int readImageMeta(FILE* f, unsigned short* count, unsigned short* width, unsigned short* height) { if (fread(count, sizeof(unsigned short), 1, f) != 1) return -1; if (fread(width, sizeof(unsigned short), 1, f) != 1) return -1; if (fread(height, sizeof(unsigned short), 1, f) != 1) return -1; return 0; } // Hilfsfunktion: Ein einzelnes Bild einlesen (NUR Pixel, OHNE Label) static GrayScaleImage readSingleImage(FILE* f, unsigned short width, unsigned short height) { GrayScaleImage img; // Breite und Höhe setzen img.width = width; img.height = height; // Speicher für Pixel reservieren size_t pixelCount = (size_t)width * (size_t)height; img.buffer = malloc(pixelCount * sizeof(GrayScalePixelType)); if (img.buffer == NULL) { // Fehlerfall: kein Speicher img.width = 0; img.height = 0; return img; } // Pixeldaten einlesen if (fread(img.buffer, sizeof(GrayScalePixelType), pixelCount, f) != pixelCount) { // Fehler beim Lesen: Speicher freigeben free(img.buffer); img.buffer = NULL; img.width = 0; img.height = 0; } return img; } // Hauptfunktion: Bildserie aus Datei lesen GrayScaleImageSeries *readImages(const char *path) { FILE *f = fopen(path, "rb"); if (f == NULL) { return NULL; // Datei konnte nicht geöffnet werden } // 1. Header prüfen if (checkFileHeader(f) != 0) { fclose(f); return NULL; // falsches Dateiformat } // 2. Metadaten lesen (Anzahl, Breite, Höhe) unsigned short count, width, height; if (readImageMeta(f, &count, &width, &height) != 0) { fclose(f); return NULL; // Metadaten konnten nicht gelesen werden } // 3. Speicher für Serie reservieren GrayScaleImageSeries *series = malloc(sizeof(GrayScaleImageSeries)); if (series == NULL) { fclose(f); return NULL; // Speicherfehler } series->count = count; series->images = malloc(count * sizeof(GrayScaleImage)); series->labels = malloc(count * sizeof(unsigned char)); if (series->images == NULL || series->labels == NULL) { free(series->images); free(series->labels); free(series); fclose(f); return NULL; } // 4. Bilder + Labels einlesen for (unsigned short i = 0; i < count; i++) { // Bild einlesen series->images[i] = readSingleImage(f, width, height); // Prüfen ob Bild erfolgreich gelesen wurde if (series->images[i].buffer == NULL) { // Fehler beim Bild-Lesen → Serie freigeben clearSeries(series); fclose(f); return NULL; } // Label einlesen if (fread(&series->labels[i], sizeof(unsigned char), 1, f) != 1) { // Fehler beim Label-Lesen → Serie freigeben clearSeries(series); fclose(f); return NULL; } } fclose(f); return series; } // Funktion: Bildserie vollständig aus dem Speicher freigeben void clearSeries(GrayScaleImageSeries *series) { if (series == NULL) { return; } // Alle einzelnen Bilder 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); series->images = NULL; } // Labels-Array freigeben if (series->labels != NULL) { free(series->labels); series->labels = NULL; } // Die Serie selbst freigeben free(series); }