From 233368318175f741b466ed92761f12e62f1151a5 Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Sat, 02 Mar 2013 17:43:57 -0500 Subject: Write a GIMP palette parser. --- (limited to 'src') diff --git a/src/resources/Makefile.am b/src/resources/Makefile.am index 4dbacdf..5f70688 100644 --- a/src/resources/Makefile.am +++ b/src/resources/Makefile.am @@ -1,4 +1,5 @@ src_resources_SOURCES = \ src/resources/resource.h src/resources/resource.c \ src/resources/image.h src/resources/image.c \ - src/resources/map.h src/resources/map.c + src/resources/map.h src/resources/map.c \ + src/resources/palette.h src/resources/palette.c diff --git a/src/resources/palette.c b/src/resources/palette.c new file mode 100644 index 0000000..3cb1a85 --- /dev/null +++ b/src/resources/palette.c @@ -0,0 +1,166 @@ +#include +#include +#include +#include "../logging.h" +#include "palette.h" +#include "resource.h" + +struct resource_table pal_res; + +static void palette_gpl_parse(const char *, SDL_Palette *); + +struct palette * +palette_get(const char *path) +{ + struct palette *pal; + + pal = (struct palette *) resource_get(&pal_res, path); + if (pal != NULL) { + resource_use((struct resource *) pal); + return pal; + } + + pal = resource_alloc(path, sizeof(*pal)); + pal->palette = malloc(sizeof(*pal->palette)); + if (pal->palette == NULL) { + err(1, "Failed to load palette \"%s\" (out of memory)", path); + } + pal->palette->colors = malloc(sizeof(*pal->palette->colors) * 240); + if (pal->palette->colors == NULL) { + err(1, "Failed to load palette \"%s\" (out of memory)", path); + } + + palette_gpl_parse(path, pal->palette); + +#ifdef DEBUG_PALETTES + { + int col_i; + + debug("Palette \"%s\"", path); + for (col_i = 0; col_i < pal->palette->ncolors; ++col_i) { + debug(" Color %3.3d: 0x%2.2x%2.2x%2.2x", + col_i, + pal->palette->colors[col_i].r, + pal->palette->colors[col_i].g, + pal->palette->colors[col_i].b); + } + } +#endif + + resource_use((struct resource *) pal); + resource_add(&pal_res, path, (struct resource *) pal); + + return pal; + +} + +static void +palette_gpl_parse(const char *path, SDL_Palette *palette) +{ + FILE *fp; + char str[1024]; + int i; + char *tok; + + /* + * See also: + * * gimp_palette_load() + * GIMP 2.8.2, app/core/gimppalette-load.c:53 + */ + + fp = fopen(path, "rb"); + if (fp == NULL) { + err(1, "Failed to load palette \"%s\" (cannot open file)", + path); + } + + /* GIMP Palette */ + if (fgets(str, sizeof(str), fp) == NULL) { + err(1, "Failed to load palette \"%s\" (cannot read line)", + path); + } + if (strncmp(str, "GIMP Palette", 12) != 0) { + err(1, "Failed to load palette \"%s\" (bad magic header)", + path); + } + + /* Name: ... */ + if (fgets(str, sizeof(str), fp) == NULL) { + err(1, "Failed to load palette \"%s\" (cannot read line)", + path); + } + if (strncmp(str, "Name: ", 6) == 0) { + /* Columns: ... */ + if (fgets(str, sizeof(str), fp) == NULL) { + err(1, "Failed to load palette \"%s\" " + "(cannot read line)", path); + } + if (strncmp(str, "Columns: ", 9) == 0) { + if (fgets(str, sizeof(str), fp) == NULL) { + err(1, "Failed to load palette \"%s\" " + "(cannot read line)", path); + } + } + } + + i = 0; + while (!feof(fp)) { + if (str[0] != '#' && str[0] != '\n') { + if (i >= 240) { + warn("Ignoring extra colors in palette \"%s\"", + path); + break; + } + + tok = strtok(str, " \t"); + if (tok != NULL) { + palette->colors[i].r = atoi(tok); + } else { + warn("Bad color definition in palette \"%s\"", + path); + } + + tok = strtok(NULL, " \t"); + if (tok != NULL) { + palette->colors[i].g = atoi(tok); + } else { + warn("Bad color definition in palette \"%s\"", + path); + } + + tok = strtok(NULL, " \t"); + if (tok != NULL) { + palette->colors[i].b = atoi(tok); + } else { + warn("Bad color definition in palette \"%s\"", + path); + } + + ++i; + } + + if (fgets(str, sizeof(str), fp) == NULL) { + err(1, "Failed to load palette \"%s\" " + "(cannot read line)", path); + } + } + + palette->ncolors = i; + fclose(fp); +} + +void +palette_free(struct palette *palette) +{ + SDL_Palette *data; + + if (palette == NULL) { + return; + } + + data = palette->palette; + if (resource_free(&pal_res, (struct resource *) palette)) { + free(data->colors); + free(data); + } +} diff --git a/src/resources/palette.h b/src/resources/palette.h new file mode 100644 index 0000000..f11a70b --- /dev/null +++ b/src/resources/palette.h @@ -0,0 +1,15 @@ +#ifndef RESOURCES_PALETTE_H +#define RESOURCES_PALETTE_H + +#include +#include "resource.h" + +struct palette { + struct resource res; + SDL_Palette *palette; +}; + +struct palette *palette_get(const char *path); +void palette_free(struct palette *palette); + +#endif -- cgit v0.9.1