diff --git a/imageInput.c b/imageInput.c index 0bb17b4..80ee0da 100644 --- a/imageInput.c +++ b/imageInput.c @@ -6,42 +6,95 @@ #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 -static int checkFileHeader(FILE *fp) -{ - if (!fp) // Datei konnte nicht geöffnet werden - return 0; - - char buffer[BUFFER_SIZE]; - size_t headerLen = strlen(FILE_HEADER_STRING); - if (headerLen >= BUFFER_SIZE) // Safety Check - return 0; - - if (fread(buffer, 1, headerLen, fp) != headerLen) - return 0; - - buffer[headerLen] = '\0'; - if (strcmp(buffer, FILE_HEADER_STRING) != 0) - return 0; - - return 1; // Header stimmt -} // TODO Vervollständigen Sie die Funktion readImages unter Benutzung Ihrer Hilfsfunktionen GrayScaleImageSeries *readImages(const char *path) { - GrayScaleImageSeries *series = NULL; + // Initialisiert einen Zeiger zur struct und reserviert Speicherplatz + GrayScaleImageSeries *series = malloc(sizeof(GrayScaleImageSeries)); + if(series == NULL){ + printf("Es ist nicht genügend Speicher übrig"); + return NULL; + } + + FILE * data = fopen(path, "rb"); + if (data == NULL){ + printf("Die Datei konnte nicht gelesen werden"); + return NULL; + } + + // Überprüfung, ob die Datei einen Header hat + char header[BUFFER_SIZE]; + fread(header, strlen(FILE_HEADER_STRING), 1, data); + header[strlen(FILE_HEADER_STRING)] ='\0'; + if(strncmp(header, FILE_HEADER_STRING, strlen(FILE_HEADER_STRING) )!= 0){ + printf("Die Datei hat keinen Header"); + fclose(data); + return NULL; + } + //liest die Anzahl der Bilder aus + fread(&series->count, sizeof(unsigned short),1, data); + series->images = malloc(series->count * sizeof(GrayScaleImage)); + if (series->images == NULL){ + printf("Es ist nicht genügend Speicher übrig"); + fclose(data); + return NULL; + } + + //liest die Höhe und Breite der Bilder aus + unsigned short height = 0, width = 0; + fread(&width, sizeof(unsigned short), 1, data); + fread(&height, sizeof(unsigned short), 1, data); + //reserviert Speicher für die Labels, die aber erst nach jedem Bild eingelesen werden + series->labels = malloc(sizeof(unsigned char) * series->count); + if (series->labels == NULL){ + printf("Es ist nicht genügend Speicher übrig"); + free(series->images); + fclose(data); + return NULL; + } + + //liest jedes Bild einzeln aus und speichert es in images + for(int counter_picture = 0 ; counter_picture < series->count; counter_picture++){ + + // für jedes Bild muss vorher eine Größe festgelegt werden, die jedoch in diesem Fall immer gleich ist + series->images[counter_picture].width = width; + series->images[counter_picture].height =height; + unsigned int size_picture = height * width; + + //reservieren des Speichers für Buffer, der die einzelnen Pixels speichert + series->images[counter_picture].buffer = malloc(size_picture* sizeof(GrayScalePixelType)); + if (series->images[counter_picture].buffer == NULL){ + printf("Es ist nicht genügend Speicher übrig"); + free(series->images); + free(series); + fclose(data); + return NULL; + } + + //einlesen der einzelnen Pixel in buffer + for(int counter_pixels = 0; counter_pixels < size_picture; counter_pixels++){ + fread(&series->images[counter_picture].buffer[counter_pixels], sizeof(unsigned char), 1, data); + } + + //einlesen der Labels + fread(&series->labels[counter_picture], sizeof(unsigned char), 1, data); + + } + + fclose(data); 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; - - free(series->images); - free(series->labels); + //erst den Speicherplatz der Pixel freigeben + for(int number= 0; number < series->count; number++){ + free(series->images[number].buffer); + } + // dann die Bilder freigeben + free(series-> images); free(series); } \ No newline at end of file diff --git a/matrix.c b/matrix.c index 557a5ee..0f183f3 100644 --- a/matrix.c +++ b/matrix.c @@ -6,47 +6,119 @@ Matrix createMatrix(unsigned int rows, unsigned int cols) { - + Matrix matrix = {NULL, 0, 0}; + + if (rows == 0 || cols == 0) + return matrix; //gibt leere Matrix zurück + + matrix.buffer = (MatrixType *)calloc(rows * cols, sizeof(MatrixType)); + if (matrix.buffer == NULL) //auf verfügbaren Speicherplatz prüfen + return matrix; + + matrix.rows = rows; + matrix.cols = cols; + return matrix; //Matrix zurückgeben } void clearMatrix(Matrix *matrix) { - //test + + if (matrix != NULL) + { + free(matrix->buffer); //Speicherplatz bereinigen + matrix->buffer = NULL; //Werte auf 0 setzen + matrix->rows = 0; + matrix->cols = 0; + } } -void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx) +void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx) { - if (matrix.buffer != NULL) - { - if (rowIdx < matrix.rows && colIdx < matrix.cols) - { - matrix.buffer[rowIdx * matrix.cols + colIdx] = value; - } - } + if (rowIdx < matrix.rows && colIdx < matrix.cols && matrix.buffer != NULL) //Prüft ob Zugriff möglich + matrix.buffer[rowIdx * matrix.cols + colIdx] = value; + //schreibt 2D element in 1D Liste: Element_Reihe*Matrix_Spalten + Element_Spalte } MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx) { - if (matrix.buffer != NULL) - { - if (rowIdx < matrix.rows && colIdx < matrix.cols) - { - return matrix.buffer[rowIdx * matrix.cols + colIdx]; - } - - } - else - { - return 0; - } + if (rowIdx >= matrix.rows || colIdx >= matrix.cols || matrix.buffer == NULL) + return 0; // Sicherheitscheck + return matrix.buffer[rowIdx * matrix.cols + colIdx]; } +// TODO: Funktionen implementieren Matrix add(const Matrix matrix1, const Matrix matrix2) { - + // immer Probe, gleiche Zeilen der Matrizen + // "Elementweise Addition": Probe, ob matrix gleiche größe hat + if (matrix1.rows == matrix2.rows && matrix1.cols == matrix2.cols) + { + Matrix result_add = createMatrix(matrix1.rows, matrix1.cols); + for (int r = 0; r < matrix1.rows; r++) + { + for (int c = 0; c < matrix1.cols; c++) + { + // first version: matrix_add[r][c] = matrix1[r][c] + matrix2[r][c] + MatrixType sum = getMatrixAt(matrix1, r, c) + getMatrixAt(matrix2, r, c); + setMatrixAt(sum, result_add, r, c); + } + } + return result_add; + } + // "Broadcasting": matrix1 hat 1 Spalte + if (matrix1.rows == matrix2.rows && matrix1.cols == 1) + { + Matrix result_add = createMatrix(matrix1.rows, matrix2.cols); + for (int r = 0; r < matrix1.rows; r++) + { + for (int c = 0; c < matrix2.cols; c++) + { + MatrixType sum = getMatrixAt(matrix2, r, c) + getMatrixAt(matrix1, r, 0); + setMatrixAt(sum, result_add, r, c); + } + } + return result_add; + } + // "Broadcasting": matrix2 hat 1 Spalte + if (matrix1.rows == matrix2.rows && matrix2.cols == 1) + { + Matrix result_add = createMatrix(matrix1.rows, matrix1.cols); + for (int r = 0; r < matrix1.rows; r++) + { + for (int c = 0; c < matrix1.cols; c++) + { + MatrixType sum = getMatrixAt(matrix1, r, c) + getMatrixAt(matrix2, r, 0); + setMatrixAt(sum, result_add, r, c); + } + } + return result_add; + } + + return createMatrix(0, 0); } Matrix multiply(const Matrix matrix1, const Matrix matrix2) { + MatrixType buffer_add; + if (!matrix1.buffer || !matrix2.buffer) // Probe ob leere Matrize vorliegt + return createMatrix(0, 0); + if (matrix1.cols != matrix2.rows) // Probe ob Spalten1 = Zeilen2 + return createMatrix(0, 0); + + Matrix result_mul = createMatrix(matrix1.rows, matrix2.cols); + + for (unsigned int index = 0; index < matrix1.rows; index++) + { + for (unsigned int shift = 0; shift < matrix2.cols; shift++) + { + buffer_add = 0; + for (unsigned int skalar = 0; skalar < matrix1.cols; skalar++) + { + buffer_add += getMatrixAt(matrix1, index, skalar) * getMatrixAt(matrix2, skalar, shift); + } + setMatrixAt(buffer_add, result_mul, index, shift); + } + } + return result_mul; } \ No newline at end of file diff --git a/matrix.h b/matrix.h index cc640d1..ad9b2c6 100644 --- a/matrix.h +++ b/matrix.h @@ -6,6 +6,11 @@ typedef float MatrixType; // TODO Matrixtyp definieren +typedef struct { + MatrixType *buffer; + unsigned int rows; + unsigned int cols; +} Matrix; Matrix createMatrix(unsigned int rows, unsigned int cols);