~ruther/CTU-FEE-B0B35APO-Semestral-project

ref: 410ece0db7bcadd8c3cd118d0994d0939699d19e CTU-FEE-B0B35APO-Semestral-project/image-viewer/src/image_loader.c -rw-r--r-- 2.6 KiB
410ece0d — František Boháček feat: add image direct write to display 3 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "image_loader.h"
#include "display_utils.h"

#include <asm-generic/errno-base.h>
#include <errno.h>
#include <magic.h>
#include <stdio.h>
#include <stdlib.h>

#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 maxBrightness;

  if (fscanf(file, "%2s %hd %hd %hd", null, &image->width, &image->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;
}
Do not follow this link