#include #include #include #include "imageInput.h" #define BUFFER_SIZE 100 #define FILE_HEADER_STRING "__info2_image_file_format__" //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) { // 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; } /* Frees the entire image series. * series: image series to free (NULL-safe). * returns nothing (void). */ void clearSeries(GrayScaleImageSeries *series) { 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); }