// load palette (.gpl or .png) #include #include /* use stb library nothings/stb: stb single-file public domain libraries for C/C++ https://github.com/nothings/stb */ #define STB_IMAGE_STATIC #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" #define CBUF_N 1024 #define TMP_PAL_NUM 1024 unsigned int *load_palette_from_gpl(char *infile, int *len_pal) { unsigned int *pal = nullptr; unsigned int tmp_pal[TMP_PAL_NUM]; FILE *fp; char str[CBUF_N]; unsigned int r, g, b; int idx = 0; for (int i = 0; i < TMP_PAL_NUM; i++) tmp_pal[i] = 0; fp = fopen(infile, "r"); if (fp == NULL) { printf("Error : Can not open %s\n", infile); *len_pal = 0; return nullptr; } while (fgets(str, CBUF_N, fp) != NULL) { str[strlen(str) - 1] = '\0'; if (strncmp("GIMP Palette", str, 12) == 0) continue; if (strncmp("Name:", str, 5) == 0) continue; if (strncmp("Columns", str, 7) == 0) continue; if (strncmp("#", str, 1) == 0) continue; sscanf(str, "%d %d %d", &r, &g, &b); // printf("%s", str); // printf("\t\tRGB : (%d, %d, %d)\n", r, g, b); tmp_pal[idx] = (r << 16) | (g << 8) | b; idx++; } fclose(fp); *len_pal = idx; pal = new unsigned int[idx]; for (int i = 0; i < idx; i++) pal[i] = tmp_pal[i]; return pal; } unsigned int *load_palette_from_img(char *infile, int *len_pal) { unsigned int *pal = nullptr; std::map pal_map; // load image unsigned char *pixels; int w; int h; int bpp; pixels = stbi_load(infile, &w, &h, &bpp, 0); if (pixels == NULL) { printf("Error : Can not load %s\n", infile); *len_pal = 0; return nullptr; } for (int y = 0; y < h; y++) { int yofs = y * w * bpp; for (int x = 0; x < w; x++) { int i = x * bpp + yofs; unsigned int col = (pixels[i + 0] << 16) | (pixels[i + 1] << 8) | pixels[i + 2]; pal_map[col] += 1; } } stbi_image_free(pixels); int n = pal_map.size(); // pal = (unsigned int *)malloc(sizeof(unsigned int) * n); pal = new unsigned int[n]; int j = 0; for (auto i = pal_map.begin(); i != pal_map.end(); i++) { pal[j] = i->first; j++; } // printf("Count palette = %d\n", j); *len_pal = j; return pal; } unsigned int *load_palette(char *infile, int *len_pal) { unsigned int *pal = nullptr; int n; char *ext = strrchr(infile, '.'); if (stricmp(".gpl", ext) == 0) { // load from .gpl (GIMP palette file) pal = load_palette_from_gpl(infile, &n); } else { // load from .png pal = load_palette_from_img(infile, &n); } *len_pal = n; return pal; } int main(int argc, char **argv) { if (argc != 2) { printf("Usage:\n %s PALETTE\n\n PALETTE (.png or .gpl)\n", argv[0]); return 0; } auto palfile = argv[1]; printf("Palette : %s\n", palfile); int len_pal = 0; unsigned int *my_pal = load_palette(palfile, &len_pal); if (my_pal == nullptr) { printf("Error : Load failure palette [%s]\n", palfile); return 1; } printf("Palette size = %d\n", len_pal); // dump palette data for (int i = 0; i < len_pal; i++) printf("%06X, ", my_pal[i]); printf("\n"); for (int i = 0; i < len_pal; i++) { unsigned int col = my_pal[i]; unsigned int r = (col >> 16) & 0x0ff; unsigned int g = (col >> 8) & 0x0ff; unsigned int b = col & 0x0ff; printf("{%d, %d, %d}, ", r, g, b); } printf("\n"); delete my_pal; }