summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2023-04-25 12:31:17 +0200
committerkdx <kikoodx@paranoici.org>2023-04-25 12:47:28 +0200
commit4a575ed4fa08f1fe8db7bdcf4ac1f53bf423876e (patch)
tree5209b4bce814d5c5a9732329ade62e09996aa5c8
parent17c351e421551867e4a08c90f604c3d7dcafa21a (diff)
downloadpximg-4a575ed4fa08f1fe8db7bdcf4ac1f53bf423876e.tar.gz
paletted conversion
-rw-r--r--pximg.c111
1 files 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);