/* * Copyright (C) 2013 Patrick "P. J." McDermott * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program. If not, see * . */ #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) { if (feof(fp)) { break; } 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); } }