#include "image_loader.h" #include "display_utils.h" #include #include #include #include #include #define BUFFER_LENGTH 4 image_error_t image_loader_load(image_t *image) { image_error_t error = image_deduce_type(image); if (error != IMERR_SUCCESS) { return error; } switch (image->type) { case IMG_PPM: return image_loader_load_ppm(image); case IMG_JPG: return image_loader_load_jpeg(image); case IMG_PNG: return image_loader_load_png(image); case IMG_UNKNOWN: return IMERR_UNKNOWN_FORMAT; } return IMERR_UNKNOWN; } image_error_t image_error_from_errno() { switch (errno) { case ENOENT: return IMERR_FILE_NOT_FOUND; case EACCES: return IMERR_FILE_NO_PERMISSIONS; default: return IMERR_FILE_CANT_OPEN; } } image_error_t image_loader_load_ppm(image_t *image) { FILE *file = fopen(image->path, "r"); if (file == NULL) { return image_error_from_errno(); } char null[10]; short height, width, maxBrightness; if (fscanf(file, "%2s %hd %hd %hd", null, &width, &height, &maxBrightness) != 4) { return IMERR_WRONG_FORMAT; } fseek(file, 1, SEEK_CUR); raw_pixel_onebit_t max = {.red = maxBrightness, .green = maxBrightness, .blue = maxBrightness}; image->pixels = malloc(image->width * image->height * sizeof(display_pixel_t)); if (image->pixels == NULL) { return IMERR_UNKNOWN; } for (int i = 0; i < image->height * image->width; i++) { raw_pixel_onebit_t pixel; if (fread(&pixel, sizeof(raw_pixel_onebit_t), 1, file) < 1) { free(image->pixels); fclose(file); return IMERR_UNKNOWN; } image->pixels[i] = raw_pixel_onebit_convert_to_display(pixel, max); } fclose(file); return IMERR_SUCCESS; } image_error_t image_loader_load_jpeg(image_t *image) { return IMERR_WRONG_FORMAT; } image_error_t image_loader_load_png(image_t *image) { return IMERR_WRONG_FORMAT; } image_error_t image_deduce_type(image_t *image) { FILE *file = fopen(image->path, "r"); if (file == NULL) { return image_error_from_errno(); } uint8_t data[BUFFER_LENGTH]; if (fread(data, 1, BUFFER_LENGTH, file) != BUFFER_LENGTH) { fclose(file); return IMERR_UNKNOWN; } fclose(file); if (data[0] == 0xFF && data[1] == 0xD8 && data[2] == 0xFF) { image->type = IMG_JPG; } else if (data[0] == 0x89 && data[1] == 0x50 && data[2] == 0x4E && data[3] == 0x47) { image->type = IMG_PNG; } else if (data[0] == 'P' && data[1] == '6') { image->type = IMG_PPM; } else { return IMERR_UNKNOWN_FORMAT; } return IMERR_SUCCESS; }