diff --git a/imageInput.c b/imageInput.c index bb30de1..310de8e 100644 --- a/imageInput.c +++ b/imageInput.c @@ -6,17 +6,223 @@ #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 + +//HilfsFunktionen: + + +/* Opens the file in binary mode. + * path: file path to open (must not be NULL). + * returns FILE* or NULL on failure. + */ +static FILE *openImageFile(const char *path) +{ + if (path == NULL) + { + return NULL; + } + + return fopen(path, "rb"); +} + +/* Reads and checks the file header. + * file: opened file to read the header from. + * returns 1 if header is valid, otherwise 0. + */ +static int readAndCheckHeader(FILE *file) +{ + size_t headerLength = strlen(FILE_HEADER_STRING); + char buffer[BUFFER_SIZE]; + + if (headerLength + 1 > BUFFER_SIZE) + { + return 0; + } + + if (fread(buffer, 1, headerLength, file) != headerLength) + { + return 0; + } + + buffer[headerLength] = '\0'; + + if (strcmp(buffer, FILE_HEADER_STRING) != 0) + { + return 0; + } + + return 1; /* Header ok */ +} + + +/* Reads metadata: image count, width, and height. + * file: file to read from; count/width/height are outputs. + * returns 1 on success or 0 on invalid/zero metadata. + */ +static int readImageMetaData(FILE *file, + unsigned short *count, + unsigned short *width, + unsigned short *height) +{ + if (fread(count, sizeof(unsigned short), 1, file) != 1) + { + return 0; + } + if (fread(width, sizeof(unsigned short), 1, file) != 1) + { + return 0; + } + if (fread(height, sizeof(unsigned short), 1, file) != 1) + { + return 0; + } + + if (*count == 0 || *width == 0 || *height == 0) + { + return 0; + } + + return 1; +} + + +//Hauptfunktion: + + +/* Loads all images + labels from a .info2 file. + * path: file path to load. + * returns a new GrayScaleImageSeries or NULL on error. + */ GrayScaleImageSeries *readImages(const char *path) { - GrayScaleImageSeries *series = NULL; - + // 1. Open the file + FILE *file = openImageFile(path); + if (file == NULL) + { + return NULL; + } + + // 2. Check the header + if (!readAndCheckHeader(file)) + { + fclose(file); + return NULL; + } + + // 3. Read image metadata + unsigned short count = 0; + unsigned short width = 0; + unsigned short height = 0; + + if (!readImageMetaData(file, &count, &width, &height)) + { + fclose(file); + return NULL; + } + + // 4. Allocate memory for image series + GrayScaleImageSeries *series = (GrayScaleImageSeries *)malloc(sizeof(GrayScaleImageSeries)); + if (series == NULL) + { + fclose(file); + return NULL; + } + + series->count = count; + series->images = (GrayScaleImage *)calloc(count, sizeof(GrayScaleImage)); + series->labels = (unsigned char *)malloc(count * sizeof(unsigned char)); + + if (series->images == NULL || series->labels == NULL) + { + free(series->images); + free(series->labels); + free(series); + fclose(file); + return NULL; + } + + // 5. Read the images and labels + for (unsigned int i = 0; i < count; i++) + { + GrayScaleImage *image = &series->images[i]; + + image->width = (unsigned int)width; + image->height = (unsigned int)height; + + size_t numPixels = (size_t)width * (size_t)height; + + image->buffer = (GrayScalePixelType *)malloc(numPixels * sizeof(GrayScalePixelType)); + if (image->buffer == NULL) + { + for (unsigned int j = 0; j < i; j++) + { + free(series->images[j].buffer); + } + free(series->images); + free(series->labels); + free(series); + fclose(file); + return NULL; + } + + if (fread(image->buffer, sizeof(GrayScalePixelType), numPixels, file) != numPixels) + { + for (unsigned int j = 0; j <= i; j++) + { + free(series->images[j].buffer); + } + free(series->images); + free(series->labels); + free(series); + fclose(file); + return NULL; + } + + if (fread(&series->labels[i], sizeof(unsigned char), 1, file) != 1) + { + for (unsigned 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 +/* Frees the entire image series. + * series: image series to free (NULL-safe). + * returns nothing (void). + */ void clearSeries(GrayScaleImageSeries *series) { -} \ No newline at end of file + if (series == NULL) + { + return; + } + + if (series->images != NULL) + { + for (unsigned int i = 0; i < series->count; i++) + { + free(series->images[i].buffer); + series->images[i].buffer = NULL; + } + free(series->images); + series->images = NULL; + } + + if (series->labels != NULL) + { + free(series->labels); + series->labels = NULL; + } + + free(series); +} diff --git a/runImageInputTests b/runImageInputTests new file mode 100755 index 0000000..11637df 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..fc02664 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: [] +...