From c8f064302c00da0a9b8db664120a5b72eb65f0a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Mon, 14 Jun 2021 21:38:12 +0200 Subject: [PATCH] feat: add ppm image loading --- image-viewer/include/image_loader.h | 9 +++ image-viewer/src/image_loader.c | 115 ++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 image-viewer/include/image_loader.h create mode 100644 image-viewer/src/image_loader.c diff --git a/image-viewer/include/image_loader.h b/image-viewer/include/image_loader.h new file mode 100644 index 0000000000000000000000000000000000000000..7693cf0f2d5fc71b423576c07a145a8b0bc6d491 --- /dev/null +++ b/image-viewer/include/image_loader.h @@ -0,0 +1,9 @@ +#include "image.h" + +image_error_t image_loader_load(image_t *image); + +image_error_t image_loader_load_ppm(image_t *image); +image_error_t image_loader_load_jpeg(image_t *image); +image_error_t image_loader_load_png(image_t *image); + +image_error_t image_deduce_type(image_t *image); diff --git a/image-viewer/src/image_loader.c b/image-viewer/src/image_loader.c new file mode 100644 index 0000000000000000000000000000000000000000..1f888c52be9ec3ff03e635d673a34a942dd25abc --- /dev/null +++ b/image-viewer/src/image_loader.c @@ -0,0 +1,115 @@ +#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; +}