diff --git a/imageInput.c b/imageInput.c index 1274e3a..6df604d 100644 --- a/imageInput.c +++ b/imageInput.c @@ -1,95 +1,96 @@ -#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 - -// TODO Vervollständigen Sie die Funktion readImages unter Benutzung Ihrer Hilfsfunktionen -GrayScaleImageSeries *readImages(const char *path) -{ - // GrayScaleImageSeries *series = NULL; - - // return series; - - FILE *file = fopen(path, "rb"); - if (file == NULL) { - return NULL; // Datei existiert nicht oder konnte nicht geöffnet werden - } - - // Überprüfe den Dateitag - char fileTag[25]; - fread(fileTag, sizeof(fileTag[0]), 24, file); - fileTag[24] = '\0'; // Null-Terminierung des Strings - - if (strcmp(fileTag, "__info2_image_file_format__") != 0) { - fclose(file); - return NULL; // Ungültiges Dateiformat - } - - // Lese die Metadaten: Anzahl der Bilder, Breite und Höhe - unsigned short numberOfImages, width, height; - fread(&numberOfImages, sizeof(numberOfImages), 1, file); - fread(&width, sizeof(width), 1, file); - fread(&height, sizeof(height), 1, file); - - // Speicher für die Bildserie und die Bilddaten allozieren - GrayScaleImageSeries *series = (GrayScaleImageSeries *)malloc(sizeof(GrayScaleImageSeries)); - if (series == NULL) { - fclose(file); - return NULL; // Speicher konnte nicht allokiert werden - } - - series->count = numberOfImages; - series->images = (GrayScaleImage *)malloc(numberOfImages * sizeof(GrayScaleImage)); - series->labels = (unsigned char *)malloc(numberOfImages * sizeof(unsigned char)); - - if (series->images == NULL || series->labels == NULL) { - free(series); - fclose(file); - return NULL; // Speicher konnte nicht allokiert werden - } - - // Lese die Bilddaten und die Labels - for (int i = 0; i < numberOfImages; i++) { - series->images[i].width = width; - series->images[i].height = height; - series->images[i].buffer = (GrayScalePixelType *)malloc(width * height * sizeof(GrayScalePixelType)); - - if (series->images[i].buffer == NULL) { - // Fehlerbehandlung: Speicher freigeben, wenn Allocation fehlschlägt - for (int j = 0; j < i; j++) { - free(series->images[j].buffer); - } - free(series->images); - free(series->labels); - free(series); - fclose(file); - return NULL; - } - - // Lese die Pixel-Daten und das Label - fread(series->images[i].buffer, sizeof(GrayScalePixelType), width * height, file); - fread(&series->labels[i], sizeof(unsigned char), 1, file); - } - - fclose(file); - return series; -} - -// TODO Vervollständigen Sie die Funktion clearSeries, welche eine Bildserie vollständig aus dem Speicher freigibt -void clearSeries(GrayScaleImageSeries *series) -{ - if (series == NULL) return; - - for (int i = 0; i < series->count; i++) { - free(series->images[i].buffer); // Speicher für das Bild freigeben - } - - free(series->images); // Speicher für die Bild-Array freigeben - free(series->labels); // Speicher für die Labels freigeben - free(series); +#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 + +// TODO Vervollständigen Sie die Funktion readImages unter Benutzung Ihrer Hilfsfunktionen +GrayScaleImageSeries *readImages(const char *path) +{ + // GrayScaleImageSeries *series = NULL; + + // return series; + + FILE *file = fopen(path, "rb"); + if (file == NULL) { + return NULL; // Datei existiert nicht oder konnte nicht geöffnet werden + } + + // Überprüfe den Dateitag + char fileTag[25]; + fread(fileTag, sizeof(fileTag[0]), 24, file); + fileTag[24] = '\0'; // Null-Terminierung des Strings + + if (strcmp(fileTag, "__info2_image_file_format__") != 0) { + fclose(file); + return NULL; // Ungültiges Dateiformat + } + + // Lese die Metadaten: Anzahl der Bilder, Breite und Höhe + unsigned short numberOfImages, width, height; + fread(&numberOfImages, sizeof(numberOfImages), 1, file); + fread(&width, sizeof(width), 1, file); + fread(&height, sizeof(height), 1, file); + + // Speicher für die Bildserie und die Bilddaten allozieren + GrayScaleImageSeries *series = (GrayScaleImageSeries *)malloc(sizeof(GrayScaleImageSeries)); + if (series == NULL) { + fclose(file); + return NULL; // Speicher konnte nicht allokiert werden + } + + series->count = numberOfImages; + series->images = (GrayScaleImage *)malloc(numberOfImages * sizeof(GrayScaleImage)); + series->labels = (unsigned char *)malloc(numberOfImages * sizeof(unsigned char)); + + if (series->images == NULL || series->labels == NULL) { + free(series); + fclose(file); + return NULL; // Speicher konnte nicht allokiert werden + } + + // Lese die Bilddaten und die Labels + for (int i = 0; i < numberOfImages; i++) { + series->images[i].width = width; + series->images[i].height = height; + series->images[i].buffer = (GrayScalePixelType *)malloc(width * height * sizeof(GrayScalePixelType)); + + if (series->images[i].buffer == NULL) { + // Fehlerbehandlung: Speicher freigeben, wenn Allocation fehlschlägt + for (int j = 0; j < i; j++) + { + free(series->images[j].buffer); + } + free(series->images); + free(series->labels); + free(series); + fclose(file); + return NULL; + } + + // Lese die Pixel-Daten und das Label + fread(series->images[i].buffer, sizeof(GrayScalePixelType), width * height, file); + fread(&series->labels[i], sizeof(unsigned char), 1, file); + } + + fclose(file); + return series; +} + +// TODO Vervollständigen Sie die Funktion clearSeries, welche eine Bildserie vollständig aus dem Speicher freigibt +void clearSeries(GrayScaleImageSeries *series) +{ + if (series == NULL) return; + + for (int i = 0; i < series->count; i++) { + free(series->images[i].buffer); // Speicher für das Bild freigeben + } + + free(series->images); // Speicher für die Bild-Array freigeben + free(series->labels); // Speicher für die Labels freigeben + free(series); } \ No newline at end of file diff --git a/matrix.c b/matrix.c index 4783a81..7512d1d 100644 --- a/matrix.c +++ b/matrix.c @@ -1,127 +1,127 @@ -#include -#include -#include "matrix.h" - -// TODO Matrix-Funktionen implementieren - -Matrix createMatrix(unsigned int rows, unsigned int cols) -{ - Matrix m = {0, 0, NULL}; - - if (rows > 0 && cols > 0) - { - m.rows = rows; - m.cols = cols; - m.buffer = malloc(rows * cols * sizeof(int)); - } - - return m; -} - -void clearMatrix(Matrix *matrix) -{ - - if (matrix == NULL) - { - return; - } - - // Speicher freigeben, falls vorhanden - free(matrix->buffer); - matrix->buffer = NULL; - - // Metadaten zurücksetzen - matrix->rows = 0; - matrix->cols = 0; -} - -void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx) -{ - matrix.buffer[rowIdx * matrix.cols + colIdx] = value; // setzte Matrix auf den Wert value am Punkt (row col) -} - -MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx) -{ - MatrixType value = 0; - - if (rowIdx < matrix.rows && colIdx < matrix.cols) - { - value = matrix.buffer[rowIdx * matrix.cols + colIdx]; // hole Wert value am Punkt (row col) - } - - return value; -} - -Matrix add(const Matrix matrix1, const Matrix matrix2) -{ - Matrix result = {0}; - - if (matrix1.rows != matrix2.rows || matrix1.cols != matrix2.cols) - { - return result; - } - - result.rows = matrix1.rows; - result.cols = matrix1.cols; - result.buffer = malloc(result.rows * result.cols * sizeof(MatrixType)); - - // wenn buffer nicht allokiert werden kann dann zurücksetzen und abbrechen - if (result.buffer == NULL) - { - result.rows = result.cols = 0; - - return result; - } - - // Matritzenaddition - for (unsigned int i = 0; i < result.rows; i++) - { - for (unsigned int j = 0; j < result.cols; j++) - { - result.buffer[i * result.cols + j] = matrix1.buffer[i * matrix1.cols + j] + matrix2.buffer[i * matrix2.cols + j]; - } - } - return result; -} - -Matrix multiply(const Matrix matrix1, const Matrix matrix2) -{ - Matrix result = {0}; - - if (matrix1.cols != matrix2.rows) - { - return result; - } - - result.rows = matrix1.rows; - result.cols = matrix2.cols; - result.buffer = malloc(result.rows * result.cols * sizeof(MatrixType)); - - // wenn buffer nicht allokiert werden kann dann zurücksetzen und abbrechen - if (result.buffer == NULL) - { - result.rows = result.cols = 0; - - return result; - } - - // Matritzenmultiplikation - - for (int r = 0; r < result.rows; r++) // Zeile in Ergebnis - { - for (int m = 0; m < result.cols; m++) // Spalte in Ergebnis - { - MatrixType sum = 0; - - for (int n = 0; n < matrix1.cols; n++) - { - sum += matrix1.buffer[r * matrix1.cols + n] * - matrix2.buffer[n * matrix2.cols + m]; - } - - result.buffer[r * result.cols + m] = sum; - } - } - - return result; +#include +#include +#include "matrix.h" + +// TODO Matrix-Funktionen implementieren + +Matrix createMatrix(unsigned int rows, unsigned int cols) +{ + Matrix m = {0, 0, NULL}; + + if (rows > 0 && cols > 0) + { + m.rows = rows; + m.cols = cols; + m.buffer = malloc(rows * cols * sizeof(int)); + } + + return m; +} + +void clearMatrix(Matrix *matrix) +{ + + if (matrix == NULL) + { + return; + } + + // Speicher freigeben, falls vorhanden + free(matrix->buffer); + matrix->buffer = NULL; + + // Metadaten zurücksetzen + matrix->rows = 0; + matrix->cols = 0; +} + +void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx) +{ + matrix.buffer[rowIdx * matrix.cols + colIdx] = value; // setzte Matrix auf den Wert value am Punkt (row col) +} + +MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx) +{ + MatrixType value = 0; + + if (rowIdx < matrix.rows && colIdx < matrix.cols) + { + value = matrix.buffer[rowIdx * matrix.cols + colIdx]; // hole Wert value am Punkt (row col) + } + + return value; +} + +Matrix add(const Matrix matrix1, const Matrix matrix2) +{ + Matrix result = {0}; + + if (matrix1.rows != matrix2.rows || matrix1.cols != matrix2.cols) + { + return result; + } + + result.rows = matrix1.rows; + result.cols = matrix1.cols; + result.buffer = malloc(result.rows * result.cols * sizeof(MatrixType)); + + // wenn buffer nicht allokiert werden kann dann zurücksetzen und abbrechen + if (result.buffer == NULL) + { + result.rows = result.cols = 0; + + return result; + } + + // Matritzenaddition + for (unsigned int i = 0; i < result.rows; i++) + { + for (unsigned int j = 0; j < result.cols; j++) + { + result.buffer[i * result.cols + j] = matrix1.buffer[i * matrix1.cols + j] + matrix2.buffer[i * matrix2.cols + j]; + } + } + return result; +} + +Matrix multiply(const Matrix matrix1, const Matrix matrix2) +{ + Matrix result = {0}; + + if (matrix1.cols != matrix2.rows) + { + return result; + } + + result.rows = matrix1.rows; + result.cols = matrix2.cols; + result.buffer = malloc(result.rows * result.cols * sizeof(MatrixType)); + + // wenn buffer nicht allokiert werden kann dann zurücksetzen und abbrechen + if (result.buffer == NULL) + { + result.rows = result.cols = 0; + + return result; + } + + // Matritzenmultiplikation + + for (int r = 0; r < result.rows; r++) // Zeile in Ergebnis + { + for (int m = 0; m < result.cols; m++) // Spalte in Ergebnis + { + MatrixType sum = 0; + + for (int n = 0; n < matrix1.cols; n++) + { + sum += matrix1.buffer[r * matrix1.cols + n] * + matrix2.buffer[n * matrix2.cols + m]; + } + + result.buffer[r * result.cols + m] = sum; + } + } + + return result; } \ No newline at end of file diff --git a/matrix.h b/matrix.h index fb042ea..a27c11a 100644 --- a/matrix.h +++ b/matrix.h @@ -1,26 +1,26 @@ -#ifndef MATRIX_H -#define MATRIX_H - -#define UNDEFINED_MATRIX_VALUE 0 - -typedef float MatrixType; - -// TODO Matrixtyp definieren - -typedef struct -{ - unsigned int rows; // Anzahl der Zeilen - unsigned int cols; // Anzahl der Spalten - MatrixType *buffer; // Zeiger auf die Matrixdaten -} Matrix; - - -Matrix createMatrix(unsigned int rows, unsigned int cols); -void clearMatrix(Matrix *matrix); -void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx); -MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx); -Matrix add(const Matrix matrix1, const Matrix matrix2); -Matrix multiply(const Matrix matrix1, const Matrix matrix2); - - -#endif +#ifndef MATRIX_H +#define MATRIX_H + +#define UNDEFINED_MATRIX_VALUE 0 + +typedef float MatrixType; + +// TODO Matrixtyp definieren + +typedef struct +{ + unsigned int rows; // Anzahl der Zeilen + unsigned int cols; // Anzahl der Spalten + MatrixType *buffer; // Zeiger auf die Matrixdaten +} Matrix; + + +Matrix createMatrix(unsigned int rows, unsigned int cols); +void clearMatrix(Matrix *matrix); +void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx); +MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx); +Matrix add(const Matrix matrix1, const Matrix matrix2); +Matrix multiply(const Matrix matrix1, const Matrix matrix2); + + +#endif diff --git a/runMatrixTests b/runMatrixTests new file mode 100755 index 0000000..4f7fb50 Binary files /dev/null and b/runMatrixTests differ