diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..0f06797 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "stdio.h": "c" + } +} \ No newline at end of file diff --git a/imageInput.c b/imageInput.c index bb30de1..4da866a 100644 --- a/imageInput.c +++ b/imageInput.c @@ -4,19 +4,170 @@ #include "imageInput.h" #define BUFFER_SIZE 100 -#define FILE_HEADER_STRING "__info2_image_file_format__" +#define FILE_HEADER_STRING "__info2_image_file_format__" // 27byte lang // TODO Implementieren Sie geeignete Hilfsfunktionen für das Lesen der Bildserie aus einer Datei +static int checkHeader(FILE *file) +{ + + int headerlen = strlen(FILE_HEADER_STRING); + + char readHeader[headerlen + 1]; + + size_t elementsRead = fread(readHeader, 1, headerlen, file); + + if (elementsRead != headerlen) + { + printf("Header länge ist nicht wie erwartet\n"); + return 0; + } + + readHeader[headerlen] = '\0'; + + if (strcmp(FILE_HEADER_STRING, readHeader) != 0) + { + printf("Header ist nicht wie erwartet\n"); + return 0; + } + + return 1; +} + +static int readMetadata(FILE *file, unsigned int *count, unsigned int *width, unsigned int *height) +{ + unsigned short tempCount = 0; + unsigned short tempWidth = 0; + unsigned short tempHeight = 0; + + if (fread(&tempCount, sizeof(unsigned short), 1, file) != 1) return 0; + if (fread(&tempWidth, sizeof(unsigned short), 1, file) != 1) return 0; + if (fread(&tempHeight, sizeof(unsigned short), 1, file) != 1) return 0; + + *count = (unsigned int)tempCount; + *width = (unsigned int)tempWidth; + *height = (unsigned int)tempHeight; + + return 1; +} + +static int readImage(FILE *file, GrayScaleImageSeries *series, unsigned int index) +{ + unsigned int numPixels = series->images[index].height * series->images[index].width; + + series->images[index].buffer = calloc(numPixels, sizeof(GrayScalePixelType)); + if (series->images[index].buffer == NULL) + return 0; + + if (fread(series->images[index].buffer, sizeof(GrayScalePixelType), numPixels, file) != numPixels) + { + free(series->images[index].buffer); + return 0; + } + + if (fread(&series->labels[index], sizeof(unsigned char), 1, file) != 1) + { + free(series->images[index].buffer); + return 0; + } + + return 1; +} // TODO Vervollständigen Sie die Funktion readImages unter Benutzung Ihrer Hilfsfunktionen GrayScaleImageSeries *readImages(const char *path) { GrayScaleImageSeries *series = NULL; - + series = malloc(sizeof(GrayScaleImageSeries)); + if (series == NULL) + return NULL; + + unsigned int count = 0; + unsigned int width = 0; + unsigned int height = 0; + + FILE *file = fopen(path, "rb"); + + if (file == NULL) + { + perror("Fehler beim öffnen der Datei\n"); + free(series); + return NULL; + } + + if (checkHeader(file) != 1) + { + printf("Fehler bei checkHeader\n"); + free(series); + fclose(file); + return NULL; + } + + if (readMetadata(file, &count, &width, &height) != 1) + { + printf("Fehler bei readMetadata\n"); + free(series); + fclose(file); + return NULL; + } + + series->count = count; + series->labels = calloc(sizeof(unsigned char), count); + series->images = calloc(sizeof(GrayScaleImage), count); + + if (series->labels == NULL || series->images == NULL) + { + printf("Speicherfehler bei Arrays\n"); + free(series->labels); + free(series->images); + free(series); + fclose(file); + return NULL; + } + + for (int i = 0; i < series->count; i++) + { + series->images[i].height = height; + series->images[i].width = width; + + if (readImage(file, series, i) != 1) + { + printf("Fehler bei readImage bei Bild Nummer: %d\n", i + 1); + + for (int j = 0; j < i; j++) + { + free(series->images[j].buffer); + } + free(series->images); + free(series->labels); + free(series); + + fclose(file); + return NULL; + } + } + + 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; + + if (series->images != NULL) { + for (int i = 0; i < series->count; i++) + { + free(series->images[i].buffer); + } + free(series->images); + } + + free(series->labels); //der container (series) muss existieren, labels kann Null sein + + free(series); + } \ No newline at end of file diff --git a/matrix.c b/matrix.c index 6ceebc8..c2fac85 100644 --- a/matrix.c +++ b/matrix.c @@ -8,7 +8,8 @@ Matrix createMatrix(unsigned int rows, unsigned int cols) { - if(rows == 0 || cols == 0){ + if (rows == 0 || cols == 0) + { Matrix matrixNull; matrixNull.rows = 0; matrixNull.cols = 0; @@ -19,9 +20,10 @@ Matrix createMatrix(unsigned int rows, unsigned int cols) Matrix matrix; matrix.rows = rows; matrix.cols = cols; - matrix.buffer = calloc(rows*cols, sizeof(MatrixType)); + matrix.buffer = calloc(rows * cols, sizeof(MatrixType)); - if(matrix.buffer == 0){ + if (matrix.buffer == 0) + { perror("Das erstellen der Matrix ist fehlgeschlagen"); clearMatrix(&matrix); return matrix; @@ -40,16 +42,18 @@ void clearMatrix(Matrix *matrix) void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx) { - if (rowIdx >= matrix.rows || colIdx >= matrix.cols) { - return; + if (rowIdx >= matrix.rows || colIdx >= matrix.cols) + { + return; } - size_t index = rowIdx * matrix.cols + colIdx; //spingt die zeilen * Anzahl der spalten (Eine Zeile = Anzahl der Spalten lang); + springt noch anzahl an spalten bis zur irhctigen Position + size_t index = rowIdx * matrix.cols + colIdx; // spingt die zeilen * Anzahl der spalten (Eine Zeile = Anzahl der Spalten lang); + springt noch anzahl an spalten bis zur irhctigen Position matrix.buffer[index] = value; } MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx) { - if(rowIdx > matrix.rows -1 || colIdx > matrix.cols -1){ + if (rowIdx > matrix.rows - 1 || colIdx > matrix.cols - 1) + { return 0; } size_t index = rowIdx * matrix.cols + colIdx; @@ -59,53 +63,59 @@ MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int co Matrix add(const Matrix matrix1, const Matrix matrix2) { - if (matrix1.rows == 0 || matrix1.cols == 0 || matrix2.rows == 0 || matrix2.cols == 0) { + if (matrix1.rows == 0 || matrix1.cols == 0 || matrix2.rows == 0 || matrix2.cols == 0) + { perror("Die Matrizen sind leer"); return createMatrix(0, 0); } - if (matrix1.rows * matrix1.cols < matrix2.rows * matrix2.cols) { + if (matrix1.rows * matrix1.cols < matrix2.rows * matrix2.cols) + { return add(matrix2, matrix1); } - if ((matrix1.rows != matrix2.rows && matrix2.rows != 1) || - (matrix1.cols != matrix2.cols && matrix2.cols != 1)) { - + if ((matrix1.rows != matrix2.rows && matrix2.rows != 1) || + (matrix1.cols != matrix2.cols && matrix2.cols != 1)) + { perror("Die Matrizen koennen nicht addiert werden"); - return createMatrix(0,0); + return createMatrix(0, 0); } Matrix matrix2Neu = matrix2; int freigabe = 0; - if (matrix1.cols != matrix2.cols) { //broadcasting + if (matrix1.cols != matrix2.cols) + { // broadcasting matrix2Neu = createMatrix(matrix1.rows, matrix1.cols); freigabe = 1; - for (unsigned rowId = 0; rowId < matrix1.rows; rowId++) { - for (unsigned colId = 0; colId < matrix1.cols; colId++) { + for (unsigned rowId = 0; rowId < matrix1.rows; rowId++) + { + for (unsigned colId = 0; colId < matrix1.cols; colId++) + { setMatrixAt(matrix2.buffer[rowId], matrix2Neu, rowId, colId); } - } - - } else if (matrix1.rows != matrix2.rows) { //broadcasting + } + else if (matrix1.rows != matrix2.rows) + { // broadcasting matrix2Neu = createMatrix(matrix1.rows, matrix1.cols); freigabe = 1; - for (unsigned colId = 0; colId < matrix1.cols; colId++) { - for (unsigned rowId = 0; rowId < matrix1.rows; rowId++) { + for (unsigned colId = 0; colId < matrix1.cols; colId++) + { + for (unsigned rowId = 0; rowId < matrix1.rows; rowId++) + { setMatrixAt(matrix2.buffer[colId], matrix2Neu, rowId, colId); } - } - } Matrix matrix = createMatrix(matrix1.rows, matrix1.cols); - for (int index = 0; index < matrix1.rows * matrix1.cols; index++){ + for (int index = 0; index < matrix1.rows * matrix1.cols; index++) + { matrix.buffer[index] = matrix1.buffer[index] + matrix2Neu.buffer[index]; } - if (freigabe == 1) + if (freigabe == 1) free(matrix2Neu.buffer); return matrix; @@ -114,19 +124,30 @@ Matrix add(const Matrix matrix1, const Matrix matrix2) Matrix multiply(const Matrix matrix1, const Matrix matrix2) { - if (matrix1.cols != matrix2.rows) { + if (matrix1.cols != matrix2.rows) + { perror("Die Matritzen koennen nicht multipliziert werden"); - return createMatrix(0,0);; + return createMatrix(0, 0); + ; + } + + if (matrix1.rows == 0 || matrix1.cols == 0 || matrix2.rows == 0 || matrix2.cols == 0) + { + perror("Die Matrizen sind leer"); + return createMatrix(0, 0); } Matrix matrix = createMatrix(matrix1.rows, matrix2.cols); int index = 0; float wert = 0.0; - for(int i = 0; i < matrix1.rows * matrix1.cols; i+=matrix1.cols){ - for(int j = 0; j < matrix2.cols; j++){ - for(int k = 0; k < matrix1.cols; k++){ - wert += matrix1.buffer[i+k] * matrix2.buffer[j+k*matrix2.cols]; + for (int i = 0; i < matrix1.rows * matrix1.cols; i += matrix1.cols) + { + for (int j = 0; j < matrix2.cols; j++) + { + for (int k = 0; k < matrix1.cols; k++) + { + wert += matrix1.buffer[i + k] * matrix2.buffer[j + k * matrix2.cols]; } matrix.buffer[index] = wert; wert = 0.0; diff --git a/runImageInputTests b/runImageInputTests new file mode 100755 index 0000000..6ee9ae7 Binary files /dev/null and b/runImageInputTests differ diff --git a/runImageInputTests.dSYM/Contents/Info.plist b/runImageInputTests.dSYM/Contents/Info.plist new file mode 100644 index 0000000..cfe5e59 --- /dev/null +++ b/runImageInputTests.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.runImageInputTests + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/runImageInputTests.dSYM/Contents/Resources/DWARF/runImageInputTests b/runImageInputTests.dSYM/Contents/Resources/DWARF/runImageInputTests new file mode 100644 index 0000000..88955c8 Binary files /dev/null and b/runImageInputTests.dSYM/Contents/Resources/DWARF/runImageInputTests differ diff --git a/runImageInputTests.dSYM/Contents/Resources/Relocations/aarch64/runImageInputTests.yml b/runImageInputTests.dSYM/Contents/Resources/Relocations/aarch64/runImageInputTests.yml new file mode 100644 index 0000000..5931690 --- /dev/null +++ b/runImageInputTests.dSYM/Contents/Resources/Relocations/aarch64/runImageInputTests.yml @@ -0,0 +1,5 @@ +--- +triple: 'arm64-apple-darwin' +binary-path: runImageInputTests +relocations: [] +... diff --git a/runMatrixTests b/runMatrixTests new file mode 100755 index 0000000..8f166d2 Binary files /dev/null and b/runMatrixTests differ diff --git a/runMatrixTests.dSYM/Contents/Info.plist b/runMatrixTests.dSYM/Contents/Info.plist new file mode 100644 index 0000000..53f0f1a --- /dev/null +++ b/runMatrixTests.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.runMatrixTests + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/runMatrixTests.dSYM/Contents/Resources/DWARF/runMatrixTests b/runMatrixTests.dSYM/Contents/Resources/DWARF/runMatrixTests new file mode 100644 index 0000000..d37b96a Binary files /dev/null and b/runMatrixTests.dSYM/Contents/Resources/DWARF/runMatrixTests differ diff --git a/runMatrixTests.dSYM/Contents/Resources/Relocations/aarch64/runMatrixTests.yml b/runMatrixTests.dSYM/Contents/Resources/Relocations/aarch64/runMatrixTests.yml new file mode 100644 index 0000000..06dc558 --- /dev/null +++ b/runMatrixTests.dSYM/Contents/Resources/Relocations/aarch64/runMatrixTests.yml @@ -0,0 +1,5 @@ +--- +triple: 'arm64-apple-darwin' +binary-path: runMatrixTests +relocations: [] +...