From 3e3254ed382af0ae8a265e4219fca427625dbb24 Mon Sep 17 00:00:00 2001 From: LukVal54 Date: Mon, 17 Nov 2025 16:29:28 +0100 Subject: [PATCH] Read image Data und readimages implementiert --- imageInput.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++-- imageInput.h | 16 +++--- 2 files changed, 146 insertions(+), 11 deletions(-) diff --git a/imageInput.c b/imageInput.c index ab24492..62ea871 100644 --- a/imageInput.c +++ b/imageInput.c @@ -54,14 +54,149 @@ static int readWidthHeightCount(FILE *fp, unsigned int *count, unsigned int *wid *height = (unsigned int)height_s; return 0; } +static GrayScaleImageSeries* allocateSeries(unsigned int count) +{ + // 1. Speicher reservieren für Hauptstruktur. Speicheradresse dieses Speicherbereichs einem Strukt ptr zuweisen + GrayScaleImageSeries *series = malloc(sizeof(GrayScaleImageSeries)); + + // 2. Prüfen, ob Speicherreservierung nicht funktioniert hat + if (series == NULL) { + return NULL; + } + + // 3. Initialiseren der Struktur. + series->count = count; + series->images = NULL; + series->labels = NULL; + + // 4. Speicher reservieren für images Struktur array + series->images = malloc(count * sizeof(GrayScaleImage));//Startadresse des images Array wird in die series gespeichert + + // 5. Prüfen, ob das images-Array nicht reserviert werden konnte + if (series->images == NULL) { + // Fehler! Rufen wir clearSeries auf, um aufzuräumen, was wir + // bisher haben (nur die 'series'-Struktur selbst). + clearSeries(series);//zu implementieren + return NULL; + } + + // 6. WICHTIG: Alle "buffer"-Zeiger in den "Seiten" initialisieren + // Das ist der "sichere" Zustand für den nächsten Schritt. + for (unsigned int i = 0; i < count; i++) { + series->images[i].buffer = NULL; + } + + // 7. "malloc" für das "labels"-Array + series->labels = malloc(count * sizeof(unsigned char)); + + // 8. Prüfen, ob das "labels"-Array reserviert werden konnte + if (series->labels == NULL) { + // Fehler! clearSeries räumt jetzt die 'series'-Struktur + // UND das 'images'-Array auf. + clearSeries(series); + return NULL; + } + + // 9. Erfolg! Alle Container sind reserviert. + return series; +} +/** + * Liest die Pixel-Daten und Labels für alle Bilder in die vorreservierte Serie. + * Reserviert den Speicher für jeden einzelnen Pixel-Buffer. + * + * @param fp Der geöffnete und bereits "vorgespulte" Datei-Zeiger. + * @param series Die vorreservierte Serie (Hülle, images-Array, labels-Array). + * @param width Die Breite, die jedes Bild hat. + * @param height Die Höhe, die jedes Bild hat. + * @return 0 bei Erfolg, -1 bei einem Speicher- oder Lesefehler. + */ +static int readImageData(FILE *fp, GrayScaleImageSeries *series, unsigned int width, unsigned int height) +{ + // 1. Berechne die Anzahl der Pixel pro Bild (mach das nur einmal) + const unsigned int numPixels = width * height; + + // 2. Gehe in einer Schleife durch jedes Bild (von 0 bis count-1) + for (unsigned int i = 0; i < series->count; i++) { + + // 3. Setze die Metadaten für das aktuelle Bild + series->images[i].width = width; + series->images[i].height = height; + + // 4. "malloc" für den Pixel-Buffer DIESES EINEN Bildes + series->images[i].buffer = malloc(numPixels * sizeof(GrayScalePixelType)); + + // 5. Prüfe auf Speicherfehler + if (series->images[i].buffer == NULL) { + // Fehler! Es gibt nicht genug Speicher. + // Gib -1 zurück. Der "Chef" (readImages) muss clearSeries aufrufen. + return -1; + } + + // 6. Lies die Pixel-Daten aus der Datei in den neuen Buffer + // Wir wollen 'numPixels' Blöcke lesen, die 'sizeof(GrayScalePixelType)' groß sind + if (fread(series->images[i].buffer, sizeof(GrayScalePixelType), numPixels, fp) != numPixels) { + // Fehler! Konnte nicht die erwartete Anzahl an Pixeln lesen. + // (z.B. Datei endet zu früh) + return -1; + } + + // 7. Lies das Label für dieses Bild aus der Datei + // Wir wollen 1 Block lesen, der 'sizeof(unsigned char)' groß ist + if (fread(&series->labels[i], sizeof(unsigned char), 1, fp) != 1) { + // Fehler! Konnte das Label nicht lesen. + return -1; + } + } // Die Schleife geht zum nächsten Bild (i++) + + // 8. Wenn die Schleife komplett durchläuft, war alles erfolgreich. + return 0; +} /* -readWidthHeightCount: liest die drei shorts ein, welche Hoehe, Breite und Anzahl sind. (SHORT!!) +readWidthHeightCount: liest die drei unsigned shorts ein, welche Hoehe, Breite und Anzahl sind. (SHORT!!) +unsigned shorts werden zeigern übergeben, welche werte in unsigned int abspeichern. */ GrayScaleImageSeries *readImages(const char *path) { + // --- Vorbereitung --- + // Wir brauchen Variablen, um die Ergebnisse der Helfer zu speichern + FILE *fp = NULL; GrayScaleImageSeries *series = NULL; - - return series; + unsigned int count = 0, width = 0, height = 0; + + // --- Schritt 1: Datei öffnen und Header prüfen --- + fp = openAndValidateHeader(path); + if (fp == NULL) { + fprintf(stderr, "Fehler: Datei konnte nicht geöffnet oder validiert werden.\n"); + return NULL; // Kein Aufräumen nötig, da nichts reserviert/geöffnet wurde + } + + // --- Schritt 2: Metadaten (count, width, height) lesen --- + if (readWidthHeightCount(fp, &count, &width, &height) != 0) { + fprintf(stderr, "Fehler: Metadaten konnten nicht gelesen werden.\n"); + fclose(fp); // Aufräumen: Datei schließen + return NULL; + } + + // --- Schritt 3: Speicher-Gerüst reservieren --- + series = allocateSeries(count); + if (series == NULL) { + fprintf(stderr, "Fehler: Speicher konnte nicht reserviert werden.\n"); + fclose(fp); // Aufräumen: Datei schließen + return NULL; + } + + // --- Schritt 4: Daten (Pixel & Labels) einlesen --- + if (readImageData(fp, series, width, height) != 0) { + fprintf(stderr, "Fehler: Bilddaten konnten nicht gelesen werden.\n"); + clearSeries(series); // Aufräumen: Speicher freigeben + fclose(fp); // Aufräumen: Datei schließen + return NULL; + } + + // --- Erfolg! --- + // Alle Schritte waren erfolgreich. + fclose(fp); // Datei schließen (wichtiger letzter Schritt) + return series; // Den Zeiger auf die fertige Datenstruktur zurückgeben } // TODO Vervollständigen Sie die Funktion clearSeries, welche eine Bildserie vollständig aus dem Speicher freigibt diff --git a/imageInput.h b/imageInput.h index 656e213..3ad6205 100644 --- a/imageInput.h +++ b/imageInput.h @@ -5,19 +5,19 @@ typedef unsigned char GrayScalePixelType; typedef struct { - GrayScalePixelType *buffer; + GrayScalePixelType *buffer; //char Array mit 0 -255 als zahlenwert. unsigned int width; - unsigned int height; -} GrayScaleImage; + unsigned int height; //Breite und Höhe eines Bildes +} GrayScaleImage;//ein Bild typedef struct { - GrayScaleImage *images; - unsigned char *labels; - unsigned int count; -} GrayScaleImageSeries; + GrayScaleImage *images;//array von Bildern mit jeweiligen Werten + unsigned char *labels;//array von Labeln zu jeweiligem Bild + unsigned int count;//Anzahl der Bilder +} GrayScaleImageSeries;//alle Bilder, also eine Bilderserie GrayScaleImageSeries *readImages(const char *path); -void clearSeries(GrayScaleImageSeries *series); +void clearSeries(GrayScaleImageSeries *series);//Zeiger auf die Bilderserie als arg #endif