mirror of
https://github.com/buserror/mii_emu.git
synced 2024-11-17 15:07:31 +00:00
11cdb8b209
List is too long... Signed-off-by: Michel Pollet <buserror@gmail.com>
109 lines
3.3 KiB
C
109 lines
3.3 KiB
C
#!/usr/bin/tcc -run
|
|
/*
|
|
* This tool is made to load a PNG, and convert it to a C array with
|
|
* ARGB8888 format, premultiplied alpha.
|
|
* It uses stb_image.h to load the PNG, which isn't included in the
|
|
* repository. The tool isn't essential to build, but is useful if you
|
|
* want icons in your menus.
|
|
* The output is a C array, with the width and height of the image
|
|
* followed by the pixels in ARGB8888 format.
|
|
* The output is written to stdout, unless -o is used.
|
|
*/
|
|
#include <ctype.h>
|
|
#define STB_IMAGE_IMPLEMENTATION
|
|
#define STBI_NO_SIMD
|
|
#define STBI_NO_HDR
|
|
#include "/opt/projects/stb/stb_image.h"
|
|
|
|
static void usage(const char *argv0)
|
|
{
|
|
fprintf(stderr,
|
|
"Usage: %s -n <array_name> "
|
|
"[-o <output_filename>] "
|
|
"[-t <int type>] "
|
|
"<PNG filename>\n",
|
|
argv0);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
const char *array_name = NULL;
|
|
const char *fname = "docs/Apple_logo_rainbow_version2_28x28.png";
|
|
const char *int_type = "uint32_t";
|
|
FILE *out = stdout;
|
|
|
|
for (int i = 1; i < argc; i++) {
|
|
if (!strcmp(argv[i], "-n") && i + 1 < argc) {
|
|
array_name = argv[i + 1];
|
|
i++;
|
|
} else if (!strcmp(argv[i], "-o") && i + 1 < argc) {
|
|
out = fopen(argv[i + 1], "w");
|
|
if (!out) {
|
|
fprintf(stderr, "Error opening %s\n", argv[i + 1]);
|
|
usage(argv[0]);
|
|
return 1;
|
|
}
|
|
i++;
|
|
} else if (!strcmp(argv[i], "-t") && i + 1 < argc) {
|
|
int_type = argv[i + 1];
|
|
i++;
|
|
} else if (!strcmp(argv[i], "-h")) {
|
|
usage(argv[0]);
|
|
return 0;
|
|
} else {
|
|
fname = argv[i];
|
|
}
|
|
}
|
|
if (!array_name) {
|
|
fprintf(stderr, "Missing array name\n");
|
|
usage(argv[0]);
|
|
return 1;
|
|
}
|
|
char define_name[256];
|
|
strcpy(define_name, array_name);
|
|
for (int i = 0; define_name[i]; i++)
|
|
define_name[i] = toupper(define_name[i]);
|
|
int width, height, channels;
|
|
unsigned char *data = stbi_load(fname, &width, &height, &channels, 0);
|
|
if (!data) {
|
|
fprintf(stderr, "Error loading image\n");
|
|
return 1;
|
|
}
|
|
fprintf(out, "// Autogenerated with:\n//\t");
|
|
for (int i = 0; i < argc; i++)
|
|
fprintf(out, " %s", argv[i]);
|
|
fprintf(out, "\n");
|
|
fprintf(out, "// Image with a W:%dpx, H:%dpx and %d channels\n"
|
|
"// Converted to ARGB8888 and premultiplied alpha\n"
|
|
"#pragma once\n",
|
|
width, height, channels);
|
|
fprintf(out, "#define %s_SIZE %d\n", define_name, 2 + (width * height));
|
|
fprintf(out, "extern const %s %s[%s_SIZE];\n", int_type, array_name, define_name);
|
|
fprintf(out, "#ifdef %s_DEFINE\n", define_name);
|
|
fprintf(out, "const %s %s[%s_SIZE] = {\n", int_type, array_name, define_name);
|
|
fprintf(out, "%d, %d, // width, height\n", width, height);
|
|
uint32_t *pixels = (uint32_t *)data;
|
|
for (int y = 0; y < height; y++) {
|
|
for (int x = 0; x < width; x++) {
|
|
uint32_t pixel = pixels[y * width + x];
|
|
// flip R and B channels
|
|
pixel = (pixel & 0xff00ff00) |
|
|
((pixel & 0xff) << 16) | ((pixel >> 16) & 0xff);
|
|
// also premultiply channels with alpha
|
|
uint32_t a = pixel >> 24;
|
|
pixel = (pixel & ~(0xff << 0)) |
|
|
((((((pixel >> 0) & 0xff) * a) >> 8) & 0xff) << 0);
|
|
pixel = (pixel & ~(0xff << 8)) |
|
|
((((((pixel >> 8) & 0xff) * a) >> 8) & 0xff) << 8);
|
|
pixel = (pixel & ~(0xff << 16)) |
|
|
((((((pixel >> 16) & 0xff) * a) >> 8) & 0xff) << 16);
|
|
fprintf(out, "0x%08x,", pixel);
|
|
if (((y * height) + x) % 8 == 7)
|
|
fprintf(out, "\n");
|
|
}
|
|
}
|
|
fprintf(out, "};\n");
|
|
fprintf(out, "#endif /* %s_DEFINE */\n", define_name);
|
|
return 0;
|
|
}
|