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

ref: bf6fdbf6fa10f949bf9af21d5acadbbf4a167707 CTU-FEE-B0B35APO-Semestral-project/mzapo-sdl/src/image_load.c -rw-r--r-- 2.3 KiB
bf6fdbf6 — František Boháček chore: add sdl project directly 1 year, 10 months 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
#include "image_load.h"
#include "sdl.h"
#include <png.h>

image_t image_load_png(char *path) {
  FILE *infile = fopen(path, "r");
  image_t empty = {0, 0, NULL};
  if (infile == NULL) {
    return empty;
  }

  png_structp png =
      png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  if (png == NULL) {
    return empty;
  }

  png_infop info = png_create_info_struct(png);
  if (info == NULL) {
    return empty;
  }

  png_init_io(png, infile);
  png_read_info(png, info);

  uint32_t width = png_get_image_width(png, info);
  uint32_t height = png_get_image_height(png, info);
  png_byte color_type = png_get_color_type(png, info);
  png_byte bit_depth = png_get_bit_depth(png, info);

  if (bit_depth == 16) {
    png_set_strip_16(png);
  }

  if (color_type == PNG_COLOR_TYPE_PALETTE) {
    png_set_palette_to_rgb(png);
  }

  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
    png_set_expand_gray_1_2_4_to_8(png);
  }

  if (png_get_valid(png, info, PNG_INFO_tRNS))
    png_set_tRNS_to_alpha(png);

  if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY ||
      color_type == PNG_COLOR_TYPE_PALETTE) {
    png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
  }

  if (color_type == PNG_COLOR_TYPE_GRAY ||
      color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
    png_set_gray_to_rgb(png);
  }

  png_read_update_info(png, info);

  png_bytep *row_pointers = malloc(sizeof(png_bytep) * height);
  if (row_pointers == NULL) {
    png_destroy_read_struct(&png, &info, NULL);
    fclose(infile);
    return empty;
  }

  for (int i = 0; i < height; i++) {
    row_pointers[i] = malloc(png_get_rowbytes(png, info));
  }

  png_read_image(png, row_pointers);

  fclose(infile);
  png_destroy_read_struct(&png, &info, NULL);

  buffer_pixel_t *pixels =
      malloc(sizeof(buffer_pixel_t) * width * height);
  if (pixels == NULL) {
    png_destroy_read_struct(&png, &info, NULL);
    free(row_pointers);
    fclose(infile);
    return empty;
  }

  for (int y = 0; y < height; y++) {
    png_bytep row = row_pointers[y];
    for (int x = 0; x < width; x++) {
      png_bytep px = &(row[x * 4]);
      pixels[y * width + x].r = px[0];
      pixels[y * width + x].g = px[1];
      pixels[y * width + x].b = px[2];
    }
  }

  image_t image = {.width = width, .height = height, .data = pixels};
  return image;
}
Do not follow this link