From 4a575ed4fa08f1fe8db7bdcf4ac1f53bf423876e Mon Sep 17 00:00:00 2001 From: kdx Date: Tue, 25 Apr 2023 12:31:17 +0200 Subject: paletted conversion --- pximg.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 101 insertions(+), 10 deletions(-) diff --git a/pximg.c b/pximg.c index 64ab30d..ba0f019 100644 --- a/pximg.c +++ b/pximg.c @@ -3,28 +3,40 @@ #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" -int main(int argc, char **argv) { - int img_w, img_h, img_col_chans; - uint8_t *img_data; +static int grayscale(char **argv); +static int indexed(char **argv); - if (argc != 3) { - fprintf(stderr, "usage: %s image.png name\n", argv[0]); +int +main(int argc, char **argv) { + if (argc != 3 && argc != 4) { + fprintf(stderr, "usage: %s image.png name [palette.png]\n", + argv[0]); return 1; } - img_data = stbi_load(argv[1], &img_w, &img_h, &img_col_chans, 0); + if (argc == 3) + return grayscale(argv); + return indexed(argv); +} + +static int +grayscale(char **argv) +{ + int img_w, img_h, img_col_chans; + uint8_t *const img_data = + stbi_load(argv[2], &img_w, &img_h, &img_col_chans, 1); if (img_data == NULL) { - fputs("error: failed to load image\n", stderr); + fprintf(stderr, "error: failed to load image\n"); return 1; } if (img_col_chans != 1) { - fputs("error: image isn't grayscale\n", stderr); + fprintf(stderr, "error: image isn't grayscale\n"); stbi_image_free(img_data); return 1; } if (img_h * img_w == 0) { - fputs("error: image size is 0\n", stderr); + fprintf(stderr, "error: image size is 0\n"); stbi_image_free(img_data); return 1; } @@ -32,7 +44,86 @@ int main(int argc, char **argv) { printf("#include \"px.h\"\nconst PxSpr %s={%d,%d,(uint8_t[]){", argv[2], img_w, img_h); for (int i = 0; i < img_w * img_h; i++) - printf("%#x,", (unsigned)img_data[i]); + printf("%u,", (unsigned)img_data[i]); + printf("}};\n"); + + stbi_image_free(img_data); + return 0; +} + +static int +indexed(char **argv) +{ + /* read palette */ + int pal_w, pal_h, pal_col_chans; + uint8_t *const pal_data = + stbi_load(argv[3], &pal_w, &pal_h, &pal_col_chans, 3); + + if (pal_data == NULL) { + fprintf(stderr, "error: failed to load palette\n"); + return 1; + } + if (pal_col_chans != 3) { + fprintf(stderr, "error: palette isn't RGB\n"); + stbi_image_free(pal_data); + return 1; + } + if (pal_w * pal_h == 0) { + fprintf(stderr, "error: palette size is 0\n"); + stbi_image_free(pal_data); + return 1; + } + if (pal_w * pal_h >= 256) { + fprintf(stderr, "error: palette size is greater than 255\n"); + stbi_image_free(pal_data); + return 1; + } + + /* store unpacked palette */ + const int pal_size = pal_w * pal_h; + uint8_t pal[256 * 3] = {0}; + for (int i = 0; i < pal_size * 3; i++) + pal[i] = pal_data[i]; + stbi_image_free(pal_data); + + /* read image */ + int img_w, img_h, img_col_chans; + uint8_t *const img_data = + stbi_load(argv[1], &img_w, &img_h, &img_col_chans, 3); + + if (img_data == NULL) { + fprintf(stderr, "error: failed to load image\n"); + return 1; + } + if (pal_col_chans != 3) { + fprintf(stderr, "error: image isn't RBG\n"); + stbi_image_free(img_data); + return 1; + } + if (img_h * img_w == 0) { + fprintf(stderr, "error: image size is 0\n"); + stbi_image_free(img_data); + return 1; + } + + printf("#include \"px.h\"\nconst PxSpr %s={%d,%d,(uint8_t[]){", + argv[2], img_w, img_h); + for (int i = 0; i < img_w * img_h; i++) { + int col = -1; + for (int k = 0; k < pal_size; k++) + if (memcmp(pal + k * 3, img_data + i * 3, 3) == 0) { + col = k; + break; + } + if (col == -1) { + fprintf(stderr, + "color at pixel %d:%d not found in palette\n", + i % img_w, i / img_w); + stbi_image_free(img_data); + return 1; + } + printf("%d,", col); + } printf("}};\n"); stbi_image_free(img_data); -- cgit v1.2.3