gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-support/png2hicolorgb/src/image_load.c
1 // image_load.c
2
3 //
4 // Handles loading PNG images and reformatting them to a usable state
5 //
6
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <stdbool.h>
10
11 #include "common.h"
12 #include "logging.h"
13 #include "image_info.h"
14 #include "options.h"
15
16 #include <defines.h>
17 #include <lodepng.h>
18
19
20 static bool image_validate(image_data *);
21 static bool image_load_png(image_data *, const char *);
22
23
24 // Validates incoming image properties
25 // Return: true if success
26 static bool image_validate(image_data * p_decoded_image) {
27
28 if (p_decoded_image->width != VALIDATE_WIDTH) {
29 ERR("Error: Image width is %d, must be %d\n", p_decoded_image->width, VALIDATE_WIDTH);
30 return false;
31 }
32
33 // TODO: There is a soft upper bound of 25 since:
34 // Width is currently fixed at 160 pixels (20 tiles)
35 // 20 tiles wide x 25 tiles high = 500 tiles
36 // Which is the highest possible within the 512 available on the CGB
37 // without reloading the tiles and maps using an offset
38 if ((p_decoded_image->height == 0) || (p_decoded_image->height > VALIDATE_HEIGHT)) {
39 ERR("Error: Image height is %d, must be between 0 and %d\n", p_decoded_image->height, VALIDATE_HEIGHT);
40 return false;
41 }
42
43 if ((p_decoded_image->height % 8) != 0u) {
44 VERBOSE("Error: Image height must be a multiple of 8, %d is not\n", p_decoded_image->height);
45 return false;
46 }
47
48 if ((p_decoded_image->width % 8) != 0u) {
49 VERBOSE("Error: Image width must be a multiple of 8, %d is not\n", p_decoded_image->width);
50 return false;
51 }
52
53 return true;
54 }
55
56
57 // Loads a PNG image image into RGB888(24) format
58 // Return: true if success
59 static bool image_load_png(image_data * p_decoded_image, const char * filename) {
60
61 bool status = true;
62 LodePNGState png_state;
63 lodepng_state_init(&png_state);
64
65 // Decode with auto conversion to RGB888(24)
66 unsigned error = lodepng_decode24_file(&p_decoded_image->p_img_data, &p_decoded_image->width, &p_decoded_image->height, filename);
67
68 if (error) {
69 status = false;
70 ERR("Error: PNG load: %u: %s\n", error, lodepng_error_text(error));
71 } else {
72 p_decoded_image->bytes_per_pixel = RGB_24SZ;
73 p_decoded_image->size = p_decoded_image->width * p_decoded_image->height * p_decoded_image->bytes_per_pixel;
74 }
75
76 // Free resources
77 lodepng_state_cleanup(&png_state);
78
79 return status;
80 }
81
82
83 // Loads an image image
84 // Return: true if success
85 bool image_load(image_data * p_decoded_image, const char * filename, const uint8_t image_type) {
86
87 bool status = true;
88
89 VERBOSE("Loading image from file: %s, type: %d\n", filename, image_type);
90
91 switch (image_type) {
92 case IMG_TYPE_PNG:
93 status = image_load_png(p_decoded_image, filename);
94 break;
95
96 default:
97 status = false;
98 ERR("Invalid image format. No image will be loaded\n");
99 break;
100 }
101
102 if (status)
103 status = image_validate(p_decoded_image);
104
105 if (status) {
106 VERBOSE("Decoded image.width: %d\n", p_decoded_image->width);
107 VERBOSE("Decoded image.height: %d\n", p_decoded_image->height);
108 VERBOSE("Decoded image.size: %d\n", p_decoded_image->size);
109 VERBOSE("Decoded image.bytes_per_pixel: %d\n", p_decoded_image->bytes_per_pixel);
110 }
111
112 return status;
113 }
114
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.